package com.silverbox.sweeporder.service.alipay.impl;

import java.io.IOException;
import java.io.Serializable;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletResponse;
import com.silverbox.core.util.*;
import com.silverbox.sweeporder.common.PayMotionConstants;
import com.silverbox.sweeporder.common.util.*;
import com.silverbox.sweeporder.common.util.Arith;
import com.silverbox.sweeporder.controller.pay.entryvo.*;
import com.silverbox.waimai.dubboApi.payMotion.PayMotionApi;
import com.silverbox.waimai.entity.*;
import com.silverbox.waimai.thread.SendMsgToMachineThread;
import com.silverbox.waimai.thread.SendServiceWindowMsgThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeCancelRequest;
import com.alipay.api.request.AlipayTradeCreateRequest;
import com.alipay.api.response.AlipayTradeCancelResponse;
import com.alipay.api.response.AlipayTradeCreateResponse;
import com.blibao.msg.ActiveMqttUtils;
import com.silverbox.core.result.CoreResponse;
import com.silverbox.core.result.CoreResponse.StatusInfo;
import com.silverbox.shopper.dubboApi.alipay.AlipayServiceApi;
import com.silverbox.shopper.dubboApi.alipay.dto.UnDiscountWaimaiItemDTO;
import com.silverbox.shopper.dubboApi.alipay.dto.UndiscountWaimaiDTO;
import com.silverbox.shopper.dubboApi.info.ShopperInfoServiceApi;
import com.silverbox.shopper.entity.AlipayApplyAuthToken;
import com.silverbox.shopper.entity.AlipayTradeRecord;
import com.silverbox.shopper.entity.BusinessWhiteList;
import com.silverbox.shopper.entity.DiningArea;
import com.silverbox.shopper.entity.Employee;
import com.silverbox.shopper.entity.EpayShopConfig;
import com.silverbox.shopper.entity.Machine;
import com.silverbox.shopper.entity.PayChannel;
import com.silverbox.shopper.entity.PayModel;
import com.silverbox.shopper.entity.Shopper;
import com.silverbox.shopper.entity.ShopperConfig;
import com.silverbox.shopper.entity.ShopperExtend;
import com.silverbox.shopper.entity.ThirdPartyAuthorization;
import com.silverbox.shopper.entity.ThirdUserInfo;
import com.silverbox.shopper.entity.extend.ShopperAndParent;
import com.silverbox.sweeporder.common.CommConstant;
import com.silverbox.sweeporder.common.CommonConstants;
import com.silverbox.sweeporder.common.Constants;
import com.silverbox.sweeporder.controller.index.vo.ShopperVO;
import com.silverbox.sweeporder.controller.pay.vo.AlipayNotify;
import com.silverbox.sweeporder.controller.pay.vo.AlipayVO;
import com.silverbox.sweeporder.controller.pay.vo.WechatPayVO;
import com.silverbox.sweeporder.controller.thread.CommonThread;
import com.silverbox.sweeporder.controller.waimai.outvo.WaimaiTradeInfo;
import com.silverbox.sweeporder.service.alipay.SweepAlipayService;
import com.silverbox.sweeporder.service.employee.EmployeeService;
import com.silverbox.sweeporder.service.redis.RedisService;
import com.silverbox.sweeporder.service.webmsg.WebMsgService;
import com.silverbox.waimai.dubboApi.order.WaimaiServiceApi;
import com.silverbox.waimai.entity.extend.WaimaiExtend;
import com.silverbox.waimai.service.order.WaimaiItemService;

@Service
public class SweepAlipayServiceImpl implements SweepAlipayService {

    private static Logger logger = LoggerFactory.getLogger(SweepAlipayServiceImpl.class);

    @Autowired
    private AlipayServiceApi alipayServiceApi;

    @Autowired
    private ShopperInfoServiceApi shopperInfoServiceApi;

    @Autowired
    private WaimaiServiceApi waimaiServiceApi;

    @Autowired
    private WebMsgService webMsgService;

    @Autowired
    private WaimaiItemService waimaiItemService;
    
    @Autowired
    private RedisService<Serializable, Object> redisService;
    
    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private PayMotionApi payMotionApi;

    @Value("${payment.PRIVATE_KEY}")
    private String PRIVATE_KEY;

    @Value("${payment.ALIPAY_PUBLIC_KEY}")
    private String ALIPAY_PUBLIC_KEY;

    @Value("${alipay2.0.PARTNER}")
    private String alipay_2_0_PARTNER;

    @Value("${payment.NOTIFY_URL}")
    private String NOTIFY_URL;

    @Value("${koubeiUploadUrl}")
    private String koubeiUploadUrl;

    @Value("${uploadOrderFlag}")
    private String uploadOrderFlag;

    @Value("${API_SERVICE}")
    private String API_SERVICE;

    @Value("${sweepUrl}")
    private String sweepUrl;

    @Value("${sweepOrderVueUrl}")
    private String sweepOrderVueUrl;

    @Value("${member.url}")
    private String memberUrl;

    @Value("${customCommonCode}")
    private String customCommonCode;

    @Value("${customSpecialCode}")
    private String customSpecialCode;

    @Value("${customPublicKey}")
    private String customPublicKey;

    @Value("${uploadUrl}")
    private String uploadUrl;

    @Value("${serviceWindowUrl}")
    private String serviceWindowUrl;

    @Value("${wechatPay.url}")
    private String wechatPayUrl;

    @Value("${ORDER_LOCK_PAY_TIME}")
    private Integer order_lock_pay_time;

    @Value("${saobei.url}")
    private String saobeiUrl;

    @Value("${antPay.url}")
    private String antPayUrl;

    @Value("${payOrder.url}")
    private String payOrderUrl;
    
    @Value("${sweepOrder.APP_ID}")
    private String appId;

    @Value("${marketing.url}")
    private String marketingUrl;

    @Override
    public AlipayApplyAuthToken getAlipayApplyAuthToken(AlipayApplyAuthToken token) {
        List<AlipayApplyAuthToken> list = alipayServiceApi.getAlipayApplyAuthToken(token);
        return Utils.isEmpty(list) ? null : list.get(0);
    }

    @Override
    public Map<String, Object> getUnDiscountAmount(Integer storeId, Long outSupportId, UndiscountWaimaiDTO waimai,
                                                   boolean priceFlag) {
        return alipayServiceApi.getUnDiscountAmount(storeId, outSupportId, waimai, priceFlag);
    }

    @Override
    public AlipayApplyAuthToken flushAuthToken(AlipayApplyAuthToken token) {
        try {
            if (token == null) {
                return null;
            }
            // add 2016-09-18 授权刷新 token一定存在
            Map<String, Object> rmap = OpenAuthTokenAppQuery.execute(token.getAppId(), token.getAuthToken());
            if ("true".equals(rmap.get("success").toString())) {
                if (!"valid".equals(rmap.get("status"))) {
                    Map<String, Object> rs = RefreshToken.execute(token);
                    if ("true".equals(rs.get("success"))) {
                        // 更新 AlipayApplyAuthToken returnMap.put("data", app);
                        token = (AlipayApplyAuthToken) rs.get("data");
                        this.updateAlipayApplyAuthToken(token);
                        token = (AlipayApplyAuthToken) rs.get("data");
                        return token;// 成功
                    } else {
                    }
                } else {
                    return token;// 成功
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public int updateAlipayApplyAuthToken(AlipayApplyAuthToken token) {
        return alipayServiceApi.updateAlipayApplyAuthToken(token);
    }

    @Override
    public int saveAlipayTradeRecord(AlipayTradeRecord record) {
        return alipayServiceApi.saveAlipayTradeRecord(record);
    }

    @Override
    public List<Machine> getMachineByStoreId(Integer storeId) {
        return shopperInfoServiceApi.getMachineByStoreId(storeId);
    }

    @Override
    public void insertTradeFundChannelByBatch(String orderNum, String tradeNo, Integer storeId, Integer shopperId,
                                              String platform, Date date, String fundBillList) {
        alipayServiceApi.insertTradeFundChannelByBatch(orderNum, tradeNo, storeId, shopperId, platform, date,
                fundBillList);
    }

    @Override
    public UndiscountWaimaiDTO getUndiscountWaimaiDTO(WaimaiExtend waimai) {
        UndiscountWaimaiDTO waimaiDTO = new UndiscountWaimaiDTO();
        waimaiDTO.setOrderNum(waimai.getOrderNum());
        waimaiDTO.setOuterSupportId(waimai.getOuterSupportId());
        List<UnDiscountWaimaiItemDTO> itemDTOList = new ArrayList<UnDiscountWaimaiItemDTO>();
        for (WaimaiItem item : waimai.getItems()) {
            UnDiscountWaimaiItemDTO itemDTO = new UnDiscountWaimaiItemDTO();
            itemDTO.setBuyCount(item.getBuyCount());
            itemDTO.setBuyPrice(item.getBuyPrice());
            itemDTO.setCategoryName(item.getCategoryName());
            itemDTO.setGive(item.getGive());
            itemDTO.setGoodsId(item.getGoodsId());
            itemDTO.setGoodsName(item.getGoodsName());
            itemDTO.setId(item.getId());
            itemDTO.setIsRefund(item.getIsRefund());
            itemDTO.setOriginalPrice(item.getOriginalPrice());
            itemDTO.setOutGoodsId(item.getOutGoodsId());
            itemDTO.setRefundCount(item.getRefundCount());
            itemDTO.setType(item.getTypeName());
            itemDTOList.add(itemDTO);
        }
        waimaiDTO.setItems(itemDTOList);
        return waimaiDTO;
    }

    @Override
    public CoreResponse<AlipayVO>  alipay(HttpServletResponse httpResponse ,AlipayEntryVO alipayEntry) {
        CoreResponse<AlipayVO> res = new CoreResponse<AlipayVO>();
        // 店铺id
        Integer storeId = alipayEntry.getStoreId();
        // 用户id
        String buyerId = alipayEntry.getBuyerId();
        // 订单号
        String orderNum = alipayEntry.getOrderNum();

        // 是否代付
        Integer isOtherPay = alipayEntry.getIsOtherPay();
        //登录模式
        Integer authMode = alipayEntry.getAuthMode();

        //会员uid
        String uid = alipayEntry.getUid();

        AlipayVO alipayVO = new AlipayVO();
        // 查询订单状态
        WaimaiExtend waimai = waimaiServiceApi.getWaimaiAndDetailByOrderNum(orderNum);
        if (waimai == null) {
            if (new Integer(1).equals(isOtherPay)) {
                alipayVO.setFlag(1);
                alipayVO.setMsg("代付订单不存在");
                alipayVO.setSuccess(false);
                res.setData(alipayVO);
                res.setSubMsg("支付失败");
                return res;
            } else {
                alipayVO.setFlag(2);
                alipayVO.setMsg("订单不存在");
                alipayVO.setSuccess(false);
                res.setData(alipayVO);
                res.setSubMsg("支付失败");
                return res;
            }
        } else {
            if (new Integer(12).equals(waimai.getOrderStatus()) && new Integer(1).equals(isOtherPay)) {
                alipayVO.setFlag(1);
                alipayVO.setMsg("订单已被取消");
                alipayVO.setSuccess(false);
                res.setSubMsg("支付失败");
                res.setData(alipayVO);
                return res;
            }
            if (waimai.getPayStatus() != null && waimai.getPayStatus().equals(new Integer(1))) {
                if (new Integer(1).equals(isOtherPay)) {
                    alipayVO.setFlag(1);
                    alipayVO.setMsg("订单已被支付");
                    alipayVO.setSuccess(false);
                    res.setData(alipayVO);
                    res.setSubMsg("支付失败");
                    return res;
                }
                alipayVO.setFlag(2);
                alipayVO.setOrderNum(waimai.getOrderNum());
                alipayVO.setMsg("订单已被支付");
                alipayVO.setSuccess(false);
                res.setData(alipayVO);
                res.setSubMsg("支付失败");
                return res;
            }
            if ((Constants.orderStatus.STATUS_THREE.getValue()).equals(waimai.getOrderStatus())) {
                alipayVO.setFlag(2);
                alipayVO.setOrderNum(waimai.getOrderNum());
                alipayVO.setMsg("商家还未接单，请联系商家");
                alipayVO.setSuccess(false);
                res.setData(alipayVO);
                res.setSubMsg("支付失败");
                return res;
            }
            // 获取店铺配置信息
            Map<String, Object> shopperConfig = shopperInfoServiceApi.getShopperAllConfig(storeId);
            String isOpenOrderLock = null == shopperConfig.get("IS_OPEN_ORDER_LOCK") ? "" : shopperConfig.get("IS_OPEN_ORDER_LOCK").toString();
            // 订单锁状态
            Integer lockStatus =  waimai.getLockStatus() == null ? 0 : waimai.getLockStatus();
            // 新增支付时添加锁,防止重复支付
            Waimai waimaiLock = new Waimai();
            if (new Integer(0).equals(lockStatus)) {
                waimaiLock.setId(waimai.getId());
                if ("1".equals(isOpenOrderLock)) {
                    waimaiLock.setLockStatus(4);
                } else {
                    waimaiLock.setLockStatus(5);
                }
                waimaiLock.setLockTime(new Date());
                waimaiServiceApi.updateWaimai(waimaiLock);
            }
            // 如果生成锁的时间超过设置时间则锁失效，重新更新锁时间
            if (waimai.getLockTime() != null && new Integer(4).equals(waimai.getLockStatus())) {
                Long lockTime = System.currentTimeMillis() - waimai.getLockTime().getTime();
                if(lockTime > 0 && lockTime < (15 * 1000)){
                    alipayVO.setFlag(4);
                    alipayVO.setMsg("同桌正在支付该订单");
                    alipayVO.setSuccess(false);
                    res.setSubMsg("订单正在支付");
                    return res;
                }
                waimaiLock.setId(waimai.getId());
                waimaiLock.setLockTime(new Date());
                waimaiServiceApi.updateWaimai(waimaiLock);
            }
            // 如果生成锁的时间超过设置时间则锁失效，重新更新锁时间
            if (waimai.getLockTime() != null && new Integer(5).equals(waimai.getLockStatus())) {
                Long lockTime = System.currentTimeMillis() - waimai.getLockTime().getTime();
                if(lockTime > 0 && lockTime < (order_lock_pay_time * 1000)){
                    alipayVO.setFlag(4);
                    alipayVO.setMsg("同桌正在支付该订单");
                    alipayVO.setSuccess(false);
                    res.setSubMsg("订单正在支付");
                    res.setData(alipayVO);
                    return res;
                }else{
                    waimaiLock.setId(waimai.getId());
                    waimaiLock.setLockTime(new Date());
                    waimaiServiceApi.updateWaimai(waimaiLock);
                }
            }
        }

        // 获取店铺信息
        ShopperAndParent shopper = shopperInfoServiceApi.getShopperAndParent(storeId);
        List<PayChannel>  payChannelByStoreId= shopperInfoServiceApi.findShopPayChannel(1, storeId, null);
        //logger.info("支付方式："+JSONObject.toJSONString(payChannelByStoreId));
        Integer payModel = 1;
        //先判断子店铺的支付方式
        if(!Utils.isEmpty(payChannelByStoreId) && !Utils.isEmpty(payChannelByStoreId.get(0))){
            //判断是否开通了蚂蚁支付
            payModel = payChannelByStoreId.get(0).getPayModel()==null?1:payChannelByStoreId.get(0).getPayModel();
        }else{
            //再查询主店铺的支付方式
            List<PayChannel>   payChannelByShopperId= shopperInfoServiceApi.findShopPayChannel(1, null,shopper.getParentId());
            if(!Utils.isEmpty(payChannelByShopperId) && !Utils.isEmpty(payChannelByShopperId.get(0))){
                payModel = payChannelByShopperId.get(0).getPayModel();
            }
        }

        if(waimai.getTotalPrice() == 0){
            PayEntryVO payEntryVO = new PayEntryVO();
            BeanUtils.copyProperties(alipayEntry,payEntryVO);
            finishOrderWhenPaySuccess(waimai,payEntryVO);
            //返回成功
            alipayVO.setFlag(3);
            alipayVO.setOrderNum(waimai.getOrderNum());
            alipayVO.setSuccess(true);
            res.setData(alipayVO);
            res.setSubMsg("支付成功");
            return res;
        }

        //使用积分抵扣
        double payTotalPrice = waimai.getTotalPrice();
        if(PayMotionConstants.Whether.TRUE.getValue().equals(alipayEntry.getIsConsumePoints())){
            //抵扣余下资金支付
            payTotalPrice = payMotionApi.consumePointsInit(waimai, PayMotionConstants.Whether.TRUE.getValue());
            //是否由积分抵扣完成
            boolean pointsFree = checkOrderPointsFree(waimai,payModel, alipayEntry);
            if(pointsFree){
                //返回成功
                alipayVO.setFlag(3);
                alipayVO.setOrderNum(waimai.getOrderNum());
                alipayVO.setSuccess(true);
                res.setData(alipayVO);
                res.setSubMsg("支付成功");
                return res;
            }
        }


        // 点餐场景类型
        String foodOrderType = getFoodOrderType(waimai);
        if (new Integer(1).equals(payModel)) {
            if(StringUtils.isEmpty(shopper.getAlipayUserId())){
                alipayVO.setFlag(2);
                alipayVO.setOrderNum(waimai.getOrderNum());
                alipayVO.setMsg("商家alipayUserId为空");
                alipayVO.setSuccess(false);
                res.setData(alipayVO);
                res.setSubMsg("支付失败");
                return res;
            }

            ShopperExtend shopExtend = shopperInfoServiceApi.getShopperExtend(shopper.getId());
            if(shopExtend==null){
                shopExtend = new ShopperExtend();
                shopExtend.setShopperId(shopper.getId());
            }

            if(!new Integer(2).equals(authMode)){
                authMode = 1;
            }
            // 获取用户信息
            ThirdUserInfo thirdUserInfo = shopperInfoServiceApi.getThirdUserInfo(buyerId, authMode);
            if (thirdUserInfo == null ) {
                res.setStatusInfo(StatusInfo.ERROR_40002);
                res.setSubMsg("用户信息异常");
                return res;
            }

            AlipayApplyAuthToken authToken = null;
            // 获取商家支付宝支付方式
            int payMethod = (new Integer(1).equals(shopExtend.getPaymentMethod()) || shopExtend.getPaymentMethod() == null)
                    ? 1 : 2;
            if (payMethod == 1 && (StringUtils.isEmpty(shopExtend.getAlipayAppId())
                    || StringUtils.isEmpty(shopExtend.getAlipayPrivateKey())
                    || StringUtils.isEmpty(shopExtend.getAlipayAlipayPublicKey()))) {
                payMethod = 2;
            }
            if (payMethod == 2) {
                AlipayApplyAuthToken token = new AlipayApplyAuthToken();
                token.setAlipayUserId(shopper.getAlipayUserId());
                authToken = getAlipayApplyAuthToken(token);
                payMethod = authToken == null ? 1 : payMethod;
            }
            AlipayClient alipayClient = AlipayUtils.initAlipayClient(PRIVATE_KEY, ALIPAY_PUBLIC_KEY, shopExtend, authToken,
                    payMethod);
            AlipayTradeCreateRequest aliPayRequest = new AlipayTradeCreateRequest();

            String outTradeNo = orderNum + RandomUtil.getRandomNum(3);

            JSONObject alipayJson = new JSONObject();
            alipayJson.fluentPut("out_trade_no", outTradeNo).fluentPut("buyer_id", buyerId).fluentPut("seller_id",
                    shopper.getAlipayUserId());
            // 获取店铺配置信息
            Map<String, Object> shopperConfig = shopperInfoServiceApi.getShopperAllConfig(storeId);
            // 店内点餐折扣
            Double discountRate = 10.0d;
            // 消息推送方式
            Integer aliyunMqtt = 0;
            // 配置了秒付数据回流后，推送商家消息至主机
            Long hostMachineId = null;
            if (null != shopperConfig) {
                discountRate = (null == shopperConfig.get("CTR_SWEEP_DISCOUNT_RATE")
                        || Utils.isEmpty(shopperConfig.get("CTR_SWEEP_DISCOUNT_RATE").toString())) ? 10.0d
                        : Double.valueOf(shopperConfig.get("CTR_SWEEP_DISCOUNT_RATE").toString());
                aliyunMqtt = (null == shopperConfig.get("CTR_ALIYUN_MQTT")
                        || Utils.isEmpty(shopperConfig.get("CTR_ALIYUN_MQTT").toString())) ? 0
                        : Integer.valueOf(shopperConfig.get("CTR_ALIYUN_MQTT").toString());
                Integer onlineDataBackflow = (null == shopperConfig.get("ONLINE_ORDER_DATA_BACKFLOW")
                        || Utils.isEmpty(shopperConfig.get("ONLINE_ORDER_DATA_BACKFLOW").toString())) ? 0
                        : Integer.valueOf(shopperConfig.get("ONLINE_ORDER_DATA_BACKFLOW").toString());
                if (new Integer(1).equals(onlineDataBackflow)) {
                    // 获取数据回流主机Id
                    EpayShopConfig epayShopConfig = shopperInfoServiceApi.getEpayShopConfig(storeId);
                    if (epayShopConfig != null) {
                        hostMachineId = epayShopConfig.getMachineId();
                    }
                }
            }
            double totalPriceAfterDiscount = Arith.round(Arith.mul(payTotalPrice, Arith.div(discountRate, 10)), 2);
            // 不打折金额
            Double unDiscountAmount = 0d;
            Double totalAmount = totalPriceAfterDiscount;
            JSONArray goodsDetail = new JSONArray();
            Map<String, Object> unDiscountAmountMap = new HashMap<String, Object>();
            if (!Utils.isEmpty(waimai.getItems())) {
                unDiscountAmountMap = getUnDiscountAmount(shopper.getId(), waimai.getOuterSupportId(),
                        getUndiscountWaimaiDTO(waimai), true);
                if (null != unDiscountAmountMap.get("details")
                        && !Utils.isEmpty(unDiscountAmountMap.get("details").toString())) {
                    goodsDetail = JSONArray.parseArray(unDiscountAmountMap.get("details").toString());
                }
                if (null != unDiscountAmountMap.get("unDiscountAmount")
                        && !Utils.isEmpty(unDiscountAmountMap.get("unDiscountAmount").toString())) {
                    unDiscountAmount = Arith.mul(Double.valueOf(unDiscountAmountMap.get("unDiscountAmount").toString()),
                            Arith.div(discountRate, 10));
                }
                /*if (null != unDiscountAmountMap.get("totalAmount")
                        && Utils.isEmpty(unDiscountAmountMap.get("totalAmount").toString())) {
                    totalAmount = Double.valueOf(unDiscountAmountMap.get("totalAmount").toString());
                }*/
            }
            alipayJson.put("goods_detail", goodsDetail);
            alipayJson.put("discountable_amount", Arith.sub(totalPriceAfterDiscount, unDiscountAmount));
            if (totalAmount < unDiscountAmount) {
                unDiscountAmount = totalAmount;
            }
            alipayJson.put("undiscountable_amount", unDiscountAmount);
            alipayJson.put("total_amount", totalAmount);
            alipayJson.put("subject",shopper.getNick() + "-消费" );
            // 查询口碑门店id
            String alipayStoreId = null;
            if (Utils.isEmpty(waimai.getKoubeiShopid())) {
                ThirdPartyAuthorization third = shopperInfoServiceApi.getThirdPartyAuthorization(storeId);
                if (null != third) {
                    alipayStoreId = null == third ? null : third.getShopId();
                }
            } else {
                alipayStoreId = waimai.getKoubeiShopid();
            }
            if (!Utils.isEmpty(alipayStoreId)) {
                alipayJson.put("alipay_store_id", alipayStoreId);
            } else {
                alipayJson.put("store_id", shopper.getId());
            }
            // 支持花呗
            JSONObject extendParamsJson = new JSONObject();
            extendParamsJson.put("sys_service_provider_id", alipay_2_0_PARTNER);
            if (!Utils.isEmpty(shopExtend.getHbFqNum()) && !Utils.isEmpty(shopExtend.getHbFqSellerPercent())) {
                extendParamsJson.put("hb_fq_num", shopExtend.getHbFqNum());
                extendParamsJson.put("hb_fq_seller_perc", shopExtend.getHbFqSellerPercent());
            }
            if (!Utils.isEmpty(foodOrderType)) {
                extendParamsJson.put("food_order_type", foodOrderType);
            }
            alipayJson.put("extend_params", extendParamsJson);
            // 桌台不为空时，传kborder_flag为order给支付宝
            if (!Utils.isEmpty(waimai.getTableNum()) || !Utils.isEmpty(waimai.getTableUid())) {
                JSONObject promoParams = new JSONObject();
                promoParams.put("kborder_flag", "order");
                alipayJson.put("promo_params", promoParams);
            }
            // 如果不属于餐馆或美食行业，则传"business_params":
            // {"bizSource":"CodeService"}至口碑，只有扫码下单才传这个参数
            if (Long.valueOf(5).equals(waimai.getOuterSupportId()) && !Utils.isEmpty(shopper.getTypeid1())
                    && ("1".equals(shopper.getTypeid1()) || "2015050700000000".equals(shopper.getTypeid1()))) {
                JSONObject businessParams = new JSONObject();
                businessParams.put("bizSource", "CodeService");
                alipayJson.put("business_params", businessParams);
            }
            alipayJson.put("timeout_express", "5m");
            aliPayRequest.setBizContent(alipayJson.toJSONString());
            //logger.info("AliPayControl.aliPay支付宝支付：" + payMethod + "   " + alipayJson.toJSONString()+"buyerPhone顾客手机号==="+alipayEntry.getBuyerPhone());
            String buyerNick = Utils.isEmpty(thirdUserInfo.getNickName()) ? "" : thirdUserInfo.getNickName();
            String avatarPath = Utils.isEmpty(thirdUserInfo.getAvatar()) ? "" : thirdUserInfo.getAvatar();

            //会员UID传给支付
            JSONObject json= new JSONObject();
            json.put("uid", uid);
            
            //支付宝支付回调地址
            aliPayRequest.setNotifyUrl(NOTIFY_URL + "pay/payNofify?" + "isOtherPay=" + (null == isOtherPay ? 0 : isOtherPay)
                    + "&buyerNick=" + buyerNick + "&avatarPath=" + avatarPath + "&aliyunMqtt=" + aliyunMqtt
                    + "&totalPriceAfterDiscount=" + totalPriceAfterDiscount + "&hostMachineId="
                    + (null == hostMachineId ? "" : hostMachineId)+"&clientOrderMode="+(alipayEntry.getClientOrderMode() == null ? "" : alipayEntry.getClientOrderMode())+"&buyerPhone="+alipayEntry.getBuyerPhone()
                    +"&reachTime="+alipayEntry.getReachTime()+"&attach="+json.toString());
            logger.info("发起支付宝支付宝，支付宝回调地址aliPayRequest:"+aliPayRequest.getNotifyUrl());
            // 领取全场券
            Map<String, String> m = new HashMap<String, String>();
            m.put("shopperId", waimai.getShopId() + "");
            m.put("buyerId", buyerId);
            CommonThread.execute("==========自动领全场券回调结果：", uploadUrl + "/ajax/receiveCoupon.htm", m);
            try {
                if (authToken != null && payMethod == 2) {
                    aliPayRequest.putOtherTextParam("app_auth_token", authToken.getAuthToken());
                }

                AlipayTradeCreateResponse response = alipayClient.execute(aliPayRequest);
                // 如果支付失败，有可能token失效，刷新token
                if (payMethod == 2 && (null == response || !response.isSuccess())) {
                    authToken = flushAuthToken(authToken);
                    if (authToken != null) {
                        aliPayRequest.putOtherTextParam("app_auth_token", authToken.getAuthToken());
                        // 再次执行
                        response = alipayClient.execute(aliPayRequest);
                    }
                }
                logger.info("支付宝支付====================response"+JSONObject.parseObject(response.getBody()));
                String errorMsg = "服务器开小差，调起支付失败";
                String alipayTradeCreateResponse = response.getBody();
                if(alipayTradeCreateResponse != null){
                    JSONObject createResponse = JSONObject.parseObject(alipayTradeCreateResponse);
                    if(createResponse != null && !"10000".equals(createResponse.getString("code"))){
                        errorMsg = createResponse.getString("sub_msg");
                    }
                }
                if (null != response && response.isSuccess()) {
                    JSONObject jsonObj = JSONObject.parseObject(response.getBody())
                            .getJSONObject("alipay_trade_create_response");
                    if ("10000".equals(jsonObj.getString("code"))) {
                        WaimaiSerialnumber record = new WaimaiSerialnumber();
                        record.setBuyerId(buyerId);
                        record.setCreateTime(new Date());
                        record.setOrderNum(orderNum);
                        record.setPayStatus(new Integer(0));
                        record.setOutTradeNo(jsonObj.getString("out_trade_no"));
                        record.setTradeNo(jsonObj.getString("trade_no"));
                        waimaiServiceApi.saveWaimaiSerialnumber(record);

                        alipayVO.setFlag(new Integer(3));
                        alipayVO.setIsOtherPay(isOtherPay);
                        alipayVO.setOrderNum(orderNum);
                        alipayVO.setTradeNo(jsonObj.getString("trade_no"));
                        alipayVO.setPayOrderNum(jsonObj.getString("out_trade_no"));
                        alipayVO.setSuccess(true);
                        res.setSubMsg("支付成功");
                        res.setData(alipayVO);
                        return res;
                    } else {
                        if (new Integer(1).equals(isOtherPay)) {
                            // 代付失败
                            alipayVO.setFlag(new Integer(1));
                            alipayVO.setMsg(jsonObj.getString("sub_msg"));
                            alipayVO.setSuccess(false);
                            res.setData(alipayVO);
                            res.setMsg("支付宝支付回调失败");
                            res.setSubMsg(errorMsg);
                            return res;
                        }
                        alipayVO.setFlag(new Integer(2));
                        alipayVO.setMsg(jsonObj.getString("sub_msg"));
                        alipayVO.setSuccess(false);
                        res.setData(alipayVO);
                        res.setMsg("支付宝支付回调失败");
                        res.setSubMsg(errorMsg);
                        return res;
                    }
                } else {
                    if (new Integer(1).equals(isOtherPay)) {
                        // 代付失败，重新进入代付订单页面
                        alipayVO.setFlag(new Integer(1));
                        alipayVO.setMsg("代付失败，请重新支付");
                        alipayVO.setOrderNum(orderNum);
                        alipayVO.setSuccess(false);
                        res.setData(alipayVO);
                        res.setSubMsg("支付失败");
                        res.setMsg(errorMsg);
                        return res;
                    }
                    alipayVO.setFlag(new Integer(2));
                    alipayVO.setSuccess(false);
                    res.setData(alipayVO);
                    res.setMsg("调用支付宝失败");
                    res.setSubMsg(errorMsg);
                    return res;
                }
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("支付宝支付异常===================="+Utils.log4jDetail(e)+"request======"+JSONObject.toJSONString(aliPayRequest));
                if (new Integer(1).equals(isOtherPay)) {
                    // 代付失败，重新进入代付订单页面
                    alipayVO.setFlag(new Integer(1));
                    alipayVO.setOrderNum(orderNum);
                    alipayVO.setSuccess(false);
                    res.setData(alipayVO);
                    res.setSubMsg("支付失败");
                    res.setMsg("支付异常");
                    return res;
                }
                alipayVO.setFlag(new Integer(2));
                alipayVO.setSuccess(false);
                res.setData(alipayVO);
                res.setMsg("支付异常");
                res.setSubMsg("支付失败");
                return res;
            }
        } else {
            // 查询是否开通统一支付聚合支付
            List<PayChannel> payChannelList = shopperInfoServiceApi.getAntPayModel(storeId);
            if (CollectionUtils.isEmpty(payChannelList)) {
                alipayVO.setFlag(5);
                alipayVO.setMsg("支付失败，无可用支付渠道");
                alipayVO.setSuccess(false);
                res.setData(alipayVO);
                return res;
            }
            //logger.info("统一支付聚合支付接口调用开始=================");
            for(PayChannel pay:payChannelList){
                try {
                    String payOrderNum = waimai.getOrderNum() + RandomUtil.getRandomNum(3);
                    //调用第三方支付方法
                    Map<String, Object> params = new HashMap<String, Object>();
                    params.put("user_id", buyerId);
                    params.put("store_id",waimai.getShopId());
                    params.put("total_amount", payTotalPrice);
                    params.put("pay_model", pay.getPayModel());
                    params.put("channel", "ALI");
                    params.put("outer_support_id", waimai.getOuterSupportId());
                    params.put("invoke_souce",1802);
                    params.put("food_order_type", foodOrderType);
                    if(waimai.getMachineId() != null){
                        params.put("machine_id", waimai.getMachineId());
                    }else{
                        List<Machine> machineList = shopperInfoServiceApi.getMachineByStoreId(waimai.getShopId());
                        if(!CollectionUtils.isEmpty(machineList)){
                            params.put("machine_id",machineList.get(0).getId());
                        }
                    }
                    params.put("order_num", waimai.getOrderNum());
                    params.put("pay_order_num", payOrderNum);
                    params.put("subject",shopper.getNick()+"-消费");
                    params.put("notify_url",sweepUrl+"/aliPay/aliPayNotify.htm");
                    logger.info("----支付宝回调通知order_num："+waimai.getOrderNum());
                    //back为2给前端放回表示统一支付聚合支付宝支付方式
                    String	success = "?back=2&state=1&msg='支付成功'&orderNumber="+waimai.getOrderNum()+"&payOrderNum="+payOrderNum;
                    String	fail = "?back=2&state=0&msg='支付失败'&orderNumber="+waimai.getOrderNum()+"&payOrderNum="+payOrderNum;
                    Integer tableInfoId = null;
                    if(!StringUtils.isEmpty(waimai.getTableUid())){
                        DiningArea diningArea = shopperInfoServiceApi.getDiningAreaByUid(waimai.getTableUid());
                        tableInfoId = diningArea.getId();
                    }

                    /*// 在线订单跳转路径
                    if(Constants.orderOutSupportId.ONLINE_ORDER.getValue().equals(waimai.getOuterSupportId())) {
                        params.put("success_url", sweepOrderVueUrl+"/#/online/payState/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/"+tableInfoId+success);
                        params.put("fail_url", sweepOrderVueUrl+"/#/online/payState/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/"+tableInfoId+fail);
                    	params.put("success_url", sweepOrderVueUrl+"/main.html/#/online/payState"+success);
                        params.put("fail_url", sweepOrderVueUrl+"/#/online/payState/"+fail);
                        // 扫码下单跳转路径
                    }else {
                        params.put("success_url",sweepOrderVueUrl+"/#/payState/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/"+tableInfoId+success);
                        params.put("fail_url", sweepOrderVueUrl+"/#/payState/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/"+tableInfoId+fail);
                    	 params.put("success_url",sweepOrderVueUrl+"/main.html#/payState/"+success);
                         params.put("fail_url", sweepOrderVueUrl+"/main.html#/payState/"+fail);
                    }*/
                    if(Constants.orderOutSupportId.ONLINE_ORDER.getValue().equals(waimai.getOuterSupportId())
                        || Constants.orderOutSupportId.WAIMAI_ORDER.getValue().equals(waimai.getOuterSupportId())) {
                        params.put("success_url",sweepOrderVueUrl+"/main.html#/online/payState/"+success);
                        params.put("fail_url", sweepOrderVueUrl+"/main.html#/online/payState/"+fail);
                        // 扫码下单跳转路径
                    }else {
                        params.put("success_url",sweepOrderVueUrl+"/main.html#/payState/"+success);
                        params.put("fail_url", sweepOrderVueUrl+"/main.html#/payState/"+fail);
                    }
                    // 查询店铺配置白名单
                    List<BusinessWhiteList> BusinessWhiteList = shopperInfoServiceApi.getShopperBusinessWhiteList(waimai.getShopId(),
                            waimai.getShopperId(), CommConstant.WHILET_NOT_SWEEP_JUMP_PAY_PAGE);
                    if (!CollectionUtils.isEmpty(BusinessWhiteList) && (Constants.orderOutSupportId.ONLINE_ORDER.getValue().equals(waimai.getOuterSupportId()) || Constants.orderOutSupportId.WAIMAI_ORDER.getValue().equals(waimai.getOuterSupportId()))) {
                        // 支付完成后不跳支付成功页面跳转我的订单页面
                        /*params.put("success_url",sweepOrderVueUrl+"/#/online/orders/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/null?orderNum="+waimai.getOrderNum());
                        params.put("fail_url", sweepOrderVueUrl+"/#/online/payState/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/"+tableInfoId+fail);*/
                    	params.put("success_url",sweepOrderVueUrl+"/#/online/orders?buyerId=" + buyerId + "&tableInfoId=" + tableInfoId + "&storeId=" + storeId +"orderNum="+waimai.getOrderNum()+"&dm=1");
                    	params.put("fail_url", sweepOrderVueUrl+"/main.html#/payState/"+fail);
                    }
                    //会员UID传给支付
                    JSONObject json= new JSONObject();
                    json.put("uid", uid);
                    params.put("attach", json.toString());
                    Map<String,Object> payMap = new HashMap<String, Object>();
                    payMap.put("out_request_no", Utils.createOrderNum(waimai.getShopId()));
                    payMap.put("method", "blibao.trade.htmlpay");
                    payMap.put("biz_content",URLEncoder.encode(JSONObject.toJSONString(params),"UTF-8"));
                    StringBuffer payUrl = new StringBuffer(antPayUrl+"?");
                    //拼接参数
                    for (String key:payMap.keySet()) {
                        payUrl.append(key+"="+payMap.get(key)+"&");
                    }
                    payUrl=payUrl.deleteCharAt(payUrl.length()-1);
                    //如果采用第三方支付，需要提前保存预点餐顾客手机号及取餐时间
                    if (!StringUtils.isEmpty(alipayEntry.getBuyerPhone())
                            || !StringUtils.isEmpty(alipayEntry.getReachTime())) {
                        Waimai payWaimai = new Waimai();
                        payWaimai.setId(waimai.getId());
                        payWaimai.setBuyerPhone(alipayEntry.getBuyerPhone());
                        if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(waimai.getOuterSupportId())){
                            payWaimai.setReachTime(alipayEntry.getReachTime());
                        }
                        waimaiServiceApi.updateWaimai(payWaimai);
                    }
                    //logger.info("统一支付聚合支付宝接口调用url组装完毕=================url："+JSONObject.toJSONString(payUrl));
                    alipayVO.setFlag(5);
                    alipayVO.setUrl(payUrl.toString());
                    alipayVO.setOrderNum(orderNum);
                    alipayVO.setIsOtherPay(isOtherPay);
                    alipayVO.setMsg("统一支付聚合支付宝方式支付");
                    alipayVO.setSuccess(true);
                    res.setData(alipayVO);
                    return res;
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.info("统一支付聚合支付宝支付异常========"+Utils.log4jDetail(e));
                    res.setStatusInfo(StatusInfo.FORBIDDEN);
                    alipayVO.setFlag(5);
                    alipayVO.setMsg("统一支付聚合支付宝方式支付异常");
                    alipayVO.setSuccess(false);
                    res.setData(alipayVO);
                    return res;
                }
            }
        }
        return res;
    }

    @Override
    public void payNotify(Map<String, Object> params) {
        AlipayNotify alipayNotify = new AlipayNotify();
        Integer aliyunMqtt = (null == params.get("aliyunMqtt") || Utils.isEmpty(params.get("aliyunMqtt").toString()))
                ? new Integer(0) : Integer.valueOf(params.get("aliyunMqtt").toString());
        alipayNotify.setAliyunMqtt(aliyunMqtt);
//		alipayNotify.setAvatarPath(null == params.get("avatarPath") ? null : params.get("avatarPath").toString());
        alipayNotify.setBuyer_id(null == params.get("buyer_id") ? "" : params.get("buyer_id").toString());
        alipayNotify
                .setBuyer_logon_id(null == params.get("buyer_logon_id") ? "" : params.get("buyer_logon_id").toString());
        alipayNotify.setBuyer_pay_amount(
                null == params.get("buyer_pay_amount") ? "" : params.get("buyer_pay_amount").toString());
        alipayNotify.setBuyerNick(null == params.get("buyerNick") ? "吃货" : params.get("buyerNick").toString());
        alipayNotify
                .setFund_bill_list(null == params.get("fund_bill_list") ? "" : params.get("fund_bill_list").toString());
        Long hostMachineId = (null == params.get("hostMachineId")
                || Utils.isEmpty(params.get("hostMachineId").toString())) ? null
                : Long.valueOf(params.get("hostMachineId").toString());
        alipayNotify.setHostMachineId(hostMachineId);
        Integer isOtherPay = (null == params.get("isOtherPay") || Utils.isEmpty(params.get("isOtherPay").toString()))
                ? new Integer(0) : Integer.valueOf(params.get("isOtherPay").toString());
        alipayNotify.setIsOtherPay(isOtherPay);
        alipayNotify.setOut_trade_no(null == params.get("out_trade_no") ? "" : params.get("out_trade_no").toString());
        alipayNotify
                .setReceipt_amount(null == params.get("receipt_amount") ? "" : params.get("receipt_amount").toString());
        alipayNotify.setTotal_amount(null == params.get("total_amount") ? "" : params.get("total_amount").toString());
        Double totalPriceAfterDiscount = (null == params.get("totalPriceAfterDiscount")
                || Utils.isEmpty(params.get("totalPriceAfterDiscount").toString())) ? 0d
                : Double.valueOf(params.get("totalPriceAfterDiscount").toString());
        alipayNotify.setTotalPriceAfterDiscount(totalPriceAfterDiscount);
        alipayNotify.setTrade_no(null == params.get("trade_no") ? "" : params.get("trade_no").toString());
        //支付状态
        String tradeStatus = Utils.isEmpty(params.get("trade_status")) ? "UNKNOW" : params.get("trade_status").toString();
        logger.info("tradeStatus="+tradeStatus);
        //交易关闭
        if("TRADE_CLOSED".equals(tradeStatus)){
            return;
        }
        //会员uid
        String attach= (String) params.get("attach");
        String uid= null;
        if(!Utils.isEmpty(attach)){
			//将json字符串转化成json对象
	        JSONObject attachJSON = JSONObject.parseObject(attach);
	        uid = attachJSON.getString("uid");
        }
        //获取扫码类型  4在线订单  5扫码下单
        Integer clientOrderMode = (null == params.get("clientOrderMode") ? 0
                : Integer.valueOf(String.valueOf(params.get("clientOrderMode"))));
        String reachTime = String.valueOf(params.get("reachTime"));
        Double totalFee = Utils.isEmpty(alipayNotify.getTotal_amount()) ? 0d
                : Double.valueOf(alipayNotify.getTotal_amount());
        Double totalPay = Utils.isEmpty(alipayNotify.getBuyer_pay_amount()) ? 0d
                : Double.valueOf(alipayNotify.getBuyer_pay_amount());
        Double totalPrice = Utils.isEmpty(alipayNotify.getReceipt_amount()) ? 0d
                : Double.valueOf(alipayNotify.getReceipt_amount());
        double thirdPromotionFee = Arith.sub(totalFee, totalPrice);// 商家优惠金额
        double payPlatformPromotionFee = Arith.sub(totalPrice, totalPay);// 支付宝优惠金额
        String buyerPhone = String.valueOf(params.get("buyerPhone"));
        String orderNum = alipayNotify.getOut_trade_no().substring(0, alipayNotify.getOut_trade_no().length() - 3);
        Waimai waimai = waimaiServiceApi.getWaimaiByOrderNum(orderNum);
        ShopperAndParent shopper = shopperInfoServiceApi.getShopperAndParent(waimai.getShopId());
        String orderDate = "";
        //获取交易时间
        if(!Utils.isEmpty(alipayNotify.getFund_bill_list())){
            JSONArray ja =  JSON.parseArray(alipayNotify.getFund_bill_list());
            if(ja!=null && ja.getJSONObject(0)!=null){
                orderDate = ja.getJSONObject(0).getString("gmt_payment");
            }
        }
        //积分支付回调的时候加入订单支付金额
        OrderPayDetail orderPayDetailByPoints = payMotionApi.getOrderPayDetailByOrderNumAndPayModel(orderNum, PayMotionConstants.OrderPayModel.MEMBER_CONSUME_POINTS.getValue());
        double orderTotalPay = totalPay;
        double orderTotalPrice = totalPrice;
        double orderTotalFee = totalFee;
        if(orderPayDetailByPoints != null){
            orderTotalPay = Arith.add(orderTotalPay,orderPayDetailByPoints.getTotalPay());
            orderTotalFee = Arith.add(orderTotalFee,orderPayDetailByPoints.getTotalFee());
            orderTotalPrice = Arith.add(orderTotalPrice,orderPayDetailByPoints.getTotalPrices());
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	logger.info("获取订单状态："+waimai.getPayStatus());
        if (new Integer(1).equals(waimai.getPayStatus())) {
            waimai.setTotalPay(orderTotalPay);
            waimai.setThirdPromotionFee(thirdPromotionFee);
            waimai.setTotalPrice(orderTotalPrice);
            waimai.setTotalFee(orderTotalFee);
            waimai.setPayplatformPromotionFee(payPlatformPromotionFee);
            waimai.setThirdPromotionFee(thirdPromotionFee);
            if(!StringUtils.isEmpty(buyerPhone)){
                waimai.setBuyerPhone(buyerPhone);
            }
            waimaiServiceApi.updateWaimai(waimai);
            // 调用支付宝上传接口上传订单
            waimaiServiceApi.uploadOrder(waimai, waimai.getOrderNum(), koubeiUploadUrl,
                    uploadOrderFlag,waimai.getOuterSupportId());
            AlipayTradeRecord record = alipayServiceApi.findAlipayTradeRecordByOrderNum(orderNum,alipayNotify.getOut_trade_no());
            if(null==record){
                record = new AlipayTradeRecord();
                record.setBuyerId(alipayNotify.getBuyer_id());
                record.setBuyerEmail(alipayNotify.getBuyer_logon_id());
                Long machineId = waimai.getMachineId();
                List<Machine> machineList = shopperInfoServiceApi.getMachineByStoreId(shopper.getId());
                if (!Utils.isEmpty(machineList) && machineId==null) {
                    machineId = machineList.get(0).getId();
                }
                record.setMachineId(machineId);
                //订单交易记录时间由创建订单时间改为当前时间
                if(StringUtils.isEmpty(orderDate)){
                    record.setOrderDate(new Date());
                }else{
                    try {
                        record.setOrderDate(sdf.parse(orderDate));
                    } catch (ParseException e) {
                        e.printStackTrace();
                        logger.error("订单交易记录时间异常==========="+orderDate+"orderNum="+orderNum);
                    }
                }
                record.setOutTradeNo(waimai.getOrderNum());
                record.setPartner(shopper.getAlipayUserId());
                record.setProductCode("WAP");
                record.setProviders(1);
                if(StringUtils.isEmpty(shopper.getAlipayUserId())){
                    record.setSellerId("");
                }else{
                    record.setSellerId(shopper.getAlipayUserId());
                }
                record.setShopperId(shopper.getId());
                record.setSubject(shopper.getNick() + "-消费");
                record.setReceiptAmount(totalPrice);
                record.setTotalFee(totalFee);
                record.setTotalPay(totalPay);
                record.setTradeNo(alipayNotify.getTrade_no());
                record.setVersionNo(2);
                record.setShopParentId(shopper.getParentId());
                record.setSource(null == waimai.getOuterSupportId() ? new Integer(5)
                        : Integer.valueOf(waimai.getOuterSupportId().toString()));
                record.setPayOrderNum(alipayNotify.getOut_trade_no());
            }else{
                record.setReceiptAmount(totalPrice);
                record.setTotalFee(totalFee);
                record.setTotalPay(totalPay);
                record.setSource(null == waimai.getOuterSupportId() ? new Integer(5)
                        : Integer.valueOf(waimai.getOuterSupportId().toString()));
            }
            // add by hyc 2019年7月8日//取餐时间更新
            record.setOrderPlaceDate(waimai.getCreateTime());
            record.setPayStatus(new Integer(1));
            alipayServiceApi.saveAlipayTradeRecord(record);
            return;
        }
        int msgType = 0;
        //在线订单 订单状态支付后改变
        logger.info("waimaiOrderStatus:"+waimai.getOrderStatus());
        if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(clientOrderMode)
                || Constants.clientOrderMode.WAIMAI_ORDER_MODE.getValue().equals(clientOrderMode)){
            msgType = 2;
            if(new Integer(-1).equals(waimai.getOrderStatus())){
                waimai.setOrderStatus(0);
            }
            //取餐时间更新
            if(!StringUtils.isEmpty(reachTime)){
                waimai.setReachTime(reachTime);
            }
            //扫码下单
        }else{
            // 增加了将取消订单被支付后改为0（出现条件：H5结账的同时，同桌取消了订单）
            if (new Integer(-1).equals(waimai.getOrderStatus()) || new Integer(12).equals(waimai.getOrderStatus())) {
                msgType = 1;
                waimai.setOrderStatus(0);
            }
        }
        if (!new Integer(1).equals(alipayNotify.getIsOtherPay())) { // 代付时不能改变buyerId
            waimai.setBuyerId(alipayNotify.getBuyer_id());
        }
        waimai.setPayStatus(1);
        waimai.setPayModel(1);
        waimai.setPayTime(new Date());
        waimai.setTradeNo(alipayNotify.getTrade_no());
        waimai.setTotalPay(orderTotalPay);
        waimai.setTotalFee(orderTotalFee);
        waimai.setThirdPromotionFee(thirdPromotionFee);
        waimai.setTotalPrice(orderTotalPrice);
        waimai.setPayplatformPromotionFee(payPlatformPromotionFee);
        waimai.setThirdPromotionFee(thirdPromotionFee);
        waimai.setIsOtherPay(alipayNotify.getIsOtherPay());
        //将会员uid保存到waimai表中
        waimai.setUid(uid);
        // add by ywc 2017年7月7日 扫码下单/网络订单增加店内扫码点餐折扣配置
        //add by litao 2019年03月18日  不保存商家优惠字段promotionprice
//		waimai.setPromotionPrice(Arith.sub(waimai.getOriginalPrice(), totalPriceAfterDiscount));
        //更新订单支付锁
        waimai.setLockStatus(0);
        //设置支付订单号
        waimai.setPayOrderNum(alipayNotify.getOut_trade_no());
        //在线订单自提时顾客手机号
        if(!StringUtils.isEmpty(buyerPhone)){
            waimai.setBuyerPhone(buyerPhone);
        }

        //在线订单支付后写入订单超时记录表
        if((Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue()).equals(clientOrderMode)
         || (Constants.clientOrderMode.WAIMAI_ORDER_MODE.getValue()).equals(clientOrderMode)){
            //获取订单超时记录表是否已经存在记录
            ReceiptTimeoutWaimai receiptWaimai = waimaiServiceApi.getReceiptTimeoutWaimai(orderNum);
            if(receiptWaimai==null){
                Date date = new Date();
                if(!StringUtils.isEmpty(orderDate)){
                    try {
                        date = sdf.parse(orderDate);
                    } catch (ParseException e) {
                        logger.error("支付回调在线订单订单超时时间异常========date"+orderDate+"orderNum="+orderNum);
                        e.printStackTrace();
                    }
                }
                //十分钟之后商家未接单会自动退款
                date.setTime(date.getTime()+10*60*1000);
                //waimai表记录在线订单支付后超时时间
                if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(waimai.getOuterSupportId())){
                    waimai.setReceiptTimeout(date);
                }
                receiptWaimai = new ReceiptTimeoutWaimai();
                receiptWaimai.setOrderNum(orderNum);
                receiptWaimai.setOuterSupportId(waimai.getOuterSupportId());
                receiptWaimai.setReceiptTimeout(date);
                receiptWaimai.setStoreId(waimai.getShopId());
                //新增在线订单订单超时记录信息
                waimaiServiceApi.saveReceiptTimeoutWaimai(receiptWaimai);
            }
        }
        logger.info("waimaiOrderStatus:"+waimai.getOrderStatus());

        // 支付类型编码
        if(null != waimai.getPayModel()){
            PayModel payModelWaimai = alipayServiceApi.getPayCodeByPayModel(waimai.getPayModel());
            if(payModelWaimai!=null){
                waimai.setPayCode(null == payModelWaimai.getPayCode()&& "".equals(payModelWaimai.getPayCode())?null:payModelWaimai.getPayCode());
            }
        }
        //20200609 存储支付明细
        Waimai waimaiPayDetailsSave = new Waimai();
        BeanUtils.copyProperties(waimai,waimaiPayDetailsSave);
        waimaiPayDetailsSave.setTotalPay(totalPay);
        waimaiPayDetailsSave.setTotalFee(totalFee);
        waimaiPayDetailsSave.setTotalPrice(totalPrice);
        payMotionApi.saveOrderPayDetails(waimaiPayDetailsSave);
        //20200609 回调处理积分消费明细
        OrderPayDetail orderPayDetail = payMotionApi.getOrderPayDetailByOrderNumAndPayModel(waimai.getOrderNum(), PayMotionConstants.OrderPayModel.MEMBER_CONSUME_POINTS.getValue());
        if(orderPayDetail != null && PayMotionConstants.PayDetailPayStatus.UNPAID.getValue().equals(orderPayDetail.getPayStatus())){
            PayModel payModelWaimai = alipayServiceApi.getPayCodeByPayModel(orderPayDetail.getPayModel());
            orderPayDetail.setPayCode(payModelWaimai.getPayCode());
            orderPayDetail = payMotionApi.executeConsumePoints(waimai, orderPayDetail);
            //积分混合使用，改变为混合支付
            waimai.setPayModel(Constants.payModel.BLEND_PAY.getValue());
            if(orderPayDetail == null){
                throw new RuntimeException("积分消费失败");
            }
        }

        if(null != waimai.getPayModel()){
            PayModel payModel = alipayServiceApi.getPayCodeByPayModel(waimai.getPayModel());
            if (payModel != null) {
                waimai.setPayCode(payModel.getPayCode());
            }
        }
        waimaiServiceApi.updateWaimai(waimai);


        // 获取用户信息
        ThirdUserInfo thirdUserInfo = shopperInfoServiceApi.getThirdUserInfo(waimai.getBuyerId(), 1);
        if (null != thirdUserInfo) {
            // add by yxy 2019年3月19日 15:00:39 创建订单时保存订单操作关联表
            WaimaiOperateRelated operateRelated = new WaimaiOperateRelated();
            // 商家Id
            operateRelated.setShopId(waimai.getShopperId());
            // 店铺Id
            operateRelated.setStoreId(waimai.getShopId());
            // 订单号
            operateRelated.setOrderNum(waimai.getOrderNum());
            // 订单来源
            operateRelated.setOuterSupportId(waimai.getOuterSupportId());
            // 订单下单时间
            operateRelated.setOrderDate(waimai.getCreateTime());
            // 操作时间类型
            operateRelated.setTimeType(CommonConstants.WaimaiOperateTimeType.ORDER_PAY.getValue());
            // 操作时间
            operateRelated.setOperateTime(new Date());
            // 操作人员类型
            operateRelated.setOperatorType(CommonConstants.WaimaiOperatorType.CUSTOMER.getValue());
            // 操作人员Id
            operateRelated.setOperatorId(thirdUserInfo.getId());
            // 操作人员员工号 扫码点餐不存
            operateRelated.setOperatorNum(null);
            // 操作人员的昵称或者名称
            operateRelated.setOperatorNick(thirdUserInfo.getNickName() == null ? "吃货" : thirdUserInfo.getNickName());
            // 订单创建时间
            operateRelated.setCreateTime(new Date());
            waimaiServiceApi.saveWaimaiOperateRelated(operateRelated);
        }
        // 调用支付宝上传接口上传订单 add by ywc 2017年3月15日
        waimaiServiceApi.uploadOrder(waimai, waimai.getOrderNum(), koubeiUploadUrl, uploadOrderFlag,waimai.getOuterSupportId());
        AlipayTradeRecord record = alipayServiceApi.findAlipayTradeRecordByOrderNum(orderNum,alipayNotify.getOut_trade_no());
        // logger.info("判断是否发送消息："+JSONObject.toJSONString(record));
        if (record == null) {
            record = new AlipayTradeRecord();
            record.setBuyerId(alipayNotify.getBuyer_id());
            record.setBuyerEmail(alipayNotify.getBuyer_logon_id());
            Long machineId = null;
            List<Machine> machineList = shopperInfoServiceApi.getMachineByStoreId(shopper.getId());
            if (!Utils.isEmpty(machineList)) {
                machineId = machineList.get(0).getId();
            }
            record.setMachineId(machineId);
            //订单交易记录时间由创建订单时间改为当前时间
            if(StringUtils.isEmpty(orderDate)){
                record.setOrderDate(new Date());
            }else{
                try {
                    record.setOrderDate(sdf.parse(orderDate));
                } catch (ParseException e) {
                    e.printStackTrace();
                    logger.info("保存交易记录时间异常+++++++++++++++"+orderDate+"orderNum="+orderNum);
                }
            }
            record.setOutTradeNo(waimai.getOrderNum());
            record.setPartner(shopper.getAlipayUserId());
            record.setProductCode("WAP");
            record.setProviders(1);
            if(StringUtils.isEmpty(shopper.getAlipayUserId())){
                record.setSellerId("");
            }else{
                record.setSellerId(shopper.getAlipayUserId());
            }
            record.setShopperId(shopper.getId());
            record.setSubject(shopper.getNick() + "-消费");
            record.setReceiptAmount(totalPrice);
            record.setTotalFee(totalFee);
            record.setTotalPay(totalPay);
            record.setTradeNo(alipayNotify.getTrade_no());
            record.setVersionNo(2);
            record.setShopParentId(shopper.getParentId());
            record.setSource(new Integer(5));
            record.setPayOrderNum(alipayNotify.getOut_trade_no());
            int count = alipayServiceApi.saveAlipayTradeRecord(record);
           // logger.info("保存交易记录======count="+count);
            DiningArea tableInfo = null;
            if (!Utils.isEmpty(waimai.getTableUid())) {
                tableInfo = shopperInfoServiceApi.getDiningAreaByUid(waimai.getTableUid());
            }
            // 配置了秒付数据回流后，推送商家消息至主机
            logger.info("payNotify->sendWebMsg:" + msgType + "," + alipayNotify.getAliyunMqtt() + ","
                    + alipayNotify.getHostMachineId());
//            Long hostMachineIdLong = null;
//            if(!Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(clientOrderMode)
//                && !Constants.clientOrderMode.WAIMAI_ORDER_MODE.equals(clientOrderMode)){
//                hostMachineId = alipayNotify.getHostMachineId();
//            }
            hostMachineId = alipayNotify.getHostMachineId();
            String msgCode = Utils.createOrderNum(waimai.getShopId());
            webMsgService.sendWebMsg(waimai, (tableInfo == null ? null : tableInfo.getMachineId()), msgType,
                    alipayNotify.getAliyunMqtt(), hostMachineId,msgCode);
            
            // add by ywc 2019年11月27日 	增加下单消息保存
			ShopperConfig sweepPayPrintObj = shopperInfoServiceApi.getShopperConfig(waimai.getShopId(), "CTR_SWEEP_PAY_PRINT");
			Integer sweepPayPrint = sweepPayPrintObj == null ? 0 : Integer.valueOf(sweepPayPrintObj.getPropValue());
			webMsgService.saveAddWaimaiMsgRecord(sweepPayPrint, waimai, tableInfo, hostMachineId, msgCode);
        }
        // 代付成功发送消息
        if (new Integer(1).equals(alipayNotify.getIsOtherPay())) {
            String to = Utils.isEmpty(waimai.getTableUid()) ? waimai.getBuyerId() : waimai.getTableUid();
            Map<String, Object> msg = new HashMap<String, Object>();
            if (!Utils.isEmpty(to)) {
                msg.put("from", "otherPay");
                msg.put("type", "otherPaySuccful");
                msg.put("avatarPath", null);
                msg.put("otherPayBuyerNick", alipayNotify.getBuyerNick());
                if ((new Integer(0)).equals(alipayNotify.getAliyunMqtt())) {
                    ActiveMqttUtils.sendMsg(to, JSONObject.toJSONString(msg));
                } else {
                    try {
                        AlibabaMQTT.send(to, JSONObject.toJSONString(msg));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            logger.info("代付成功发送消息: " + "to:" + to + "  msg:" + JSONObject.toJSONString(msg));
        }
        // 有商家优惠，上传商品优惠信息
        if (thirdPromotionFee > 0) {
            Map<String, String> paramMap = new HashMap<String, String>();
            paramMap.put("shopperPid", waimai.getShopperId() + "");
            paramMap.put("shopperId", waimai.getShopId() + "");
            paramMap.put("machineId", waimai.getMachineId() == null ? "" : (waimai.getMachineId() + ""));
            paramMap.put("alipayUserId", shopper.getAlipayUserId() + "");
            paramMap.put("tradeNo", waimai.getTradeNo());// 交易流水号
            WaimaiExtend waimaiEx = waimaiServiceApi.getWaimaiAndDetailByOrderNum(orderNum);
            paramMap.put("goodsDetail", getGoodsDetailJSON(waimaiEx));
            if(Constants.orderOutSupportId.ONLINE_ORDER.getValue().equals(waimai.getOuterSupportId())){
                paramMap.put("outerSupportId", "4");
            }else if(Constants.orderOutSupportId.SCAN_ORDER.getValue().equals(waimai.getOuterSupportId())){
                paramMap.put("outerSupportId", "5");
            }else if(Constants.orderOutSupportId.KOUBEI_ORDER.getValue().equals(waimai.getOuterSupportId())){
                paramMap.put("outerSupportId", "103");
            }else if(Constants.orderOutSupportId.WAIMAI_ORDER.getValue().equals(waimai.getOuterSupportId())){
                paramMap.put("outerSupportId", "81");
            }
            paramMap.put("shopperName", waimai.getShopName());
            CommonThread.execute("上传商品优惠信息", API_SERVICE + "/ajax/saveThirdDiscountVerifyRecord2.htm", paramMap);
        }
        // 生活号结账通知
        ShopperVO shopperVO = new ShopperVO();
        if (shopper != null) {
            BeanUtils.copyProperties(shopper, shopperVO);
            shopperVO.setParentId(shopper.getParentId());
            if (shopper.getParentInfo() != null) {
                shopperVO.setParentNick(shopper.getParentInfo().getNick());
                shopperVO.setParentMinLogo(shopper.getParentInfo().getMinLogo());
            }
        }

        waimaiServiceApi.sendServiceWindowMsg(waimai, shopper.getAlipayUserId(), shopper.getNick(),
                shopper.getAddress(), sweepUrl, serviceWindowUrl, "3");

        // 撤销其他等待支付的订单
        List<WaimaiSerialnumber> serialList = waimaiServiceApi.getWaimaiSerialnumberByOrderNum(orderNum);
        if (!Utils.isEmpty(serialList)) {
            Map<String, String> n = new HashMap<String, String>();
            JSONArray jsonArr = new JSONArray();
            for (WaimaiSerialnumber s : serialList) {
                JSONObject json = new JSONObject();
                json.put("out_trade_no", s.getOutTradeNo());
                json.put("trade_no", s.getTradeNo());
                json.put("pay_status", s.getPayStatus());
                json.put("buyer_id", s.getBuyerId());
                jsonArr.add(json);
            }
            logger.info("=============out_trade_no===================" + jsonArr.toString());
            n.put("cancelJSON", jsonArr.toString());
            n.put("shopperId", waimai.getShopId() + "");
            n.put("orderNum", orderNum);
            n.put("outTradeNo", alipayNotify.getOut_trade_no());
            CommonThread.execute("==========关闭支付宝已支付订单里面的等待支付订单：" + waimai.getOrderNum(), sweepOrderVueUrl + "/pay/cancel", n);
        }
        // 保存资金渠道
        if (!Utils.isEmpty(alipayNotify.getFund_bill_list())) {
            alipayServiceApi.insertTradeFundChannelByBatch(orderNum, alipayNotify.getTrade_no(), shopper.getId(),
                    shopper.getParentId(), "alipay", new Date(), alipayNotify.getFund_bill_list());
        }
        //核销优惠订单 20200407
        payMotionApi.executeVouchersVerify(waimai);
        return;
    }

    private String getGoodsDetailJSON(WaimaiExtend waimai) {
        JSONArray array = new JSONArray();
        if (waimai != null && waimai.getItems() != null && waimai.getItems().size() > 0) {
            for (WaimaiItem item : waimai.getItems()) {
                JSONObject json = new JSONObject();
                json.put("goods_id", item.getGoodsId());
                json.put("goods_name", item.getGoodsName());
                json.put("quantity", item.getBuyCount());
                json.put("price", item.getOriginalPrice());
                array.add(json);
            }
        }
        return array.toJSONString();
    }

    /**
     * 获取点餐场景类型
     * add by ywc 2019年12月2日 	
     * @param waimai
     * @return
     */
    private String getFoodOrderType(Waimai waimai) {
    	// 点餐场景类型
        String foodOrderType = "";
        if (new Long(5).equals(waimai.getOuterSupportId()) || new Long(101).equals(waimai.getOuterSupportId())
                || new Long(103).equals(waimai.getOuterSupportId())) {
            foodOrderType = "qr_order";
        } else if (new Long(4).equals(waimai.getOuterSupportId())) {
            foodOrderType = "pre_order";
        } else if (new Long(81).equals(waimai.getOuterSupportId())) {
            foodOrderType = "home_delivery";
        }
        return foodOrderType;
    }

    //会员卡支付
    @Override
    public CoreResponse<StatusInfo> vipPay(VipPayEntryDto vipPayEntryVO) {
        CoreResponse<StatusInfo> res = new CoreResponse<StatusInfo>();
        String orderNum = vipPayEntryVO.getOrderNum();
        String uid = vipPayEntryVO.getUid();
        Integer clientOrderMode = vipPayEntryVO.getClientOrderMode();
        String buyerId = vipPayEntryVO.getBuyerId();

        Waimai waimai = waimaiServiceApi.getWaimaiByOrderNum(orderNum);
        if (waimai == null) {
            res.setStatusInfo(StatusInfo.NORESOURCE);
            res.setMsg("订单不存在");
            return res;
        }
        if (new Integer(1).equals(waimai.getPayStatus())) {
            res.setStatusInfo(StatusInfo.FORBIDDEN);
            res.setMsg("订单已被支付");
            return res;
        }
        if(Constants.orderStatus.STATUS_THREE.getValue().equals(waimai.getOrderStatus())){
            res.setStatusInfo(StatusInfo.FORBIDDEN);
            res.setMsg("商家还未接单，请联系商家");
            return res;
        }
        // 获取店铺配置信息
        Map<String, Object> shopperConfig = shopperInfoServiceApi.getShopperAllConfig(waimai.getShopId());
        String isOpenOrderLock = null == shopperConfig.get("IS_OPEN_ORDER_LOCK") ? "" : shopperConfig.get("IS_OPEN_ORDER_LOCK").toString();
        // 订单锁状态
        Integer lockStatus =  waimai.getLockStatus() == null ? 0 : waimai.getLockStatus();
        // 新增支付时添加锁,防止重复支付
        Waimai waimaiLock = new Waimai();
        if (new Integer(0).equals(lockStatus)) {
            waimaiLock.setId(waimai.getId());
            if ("1".equals(isOpenOrderLock)) {
                waimaiLock.setLockStatus(4);
            } else {
                waimaiLock.setLockStatus(5);
            }
            waimaiLock.setLockTime(new Date());
            waimaiServiceApi.updateWaimai(waimaiLock);
        }
        // 如果生成锁的时间超过设置时间则锁失效，重新更新锁时间
        if (waimai.getLockTime() != null && new Integer(4).equals(waimai.getLockStatus())) {
            Long lockTime = System.currentTimeMillis() - waimai.getLockTime().getTime();
            if(lockTime > 0 && lockTime < (15 * 1000)){
                res.setData(StatusInfo.BUSINESS);
                res.setSubMsg("订单正在支付");
                return res;
            }
            waimaiLock.setId(waimai.getId());
            waimaiLock.setLockTime(new Date());
            waimaiServiceApi.updateWaimai(waimaiLock);
        }
        // 如果生成锁的时间超过设置时间则锁失效，重新更新锁时间
        if (waimai.getLockTime() != null && new Integer(5).equals(waimai.getLockStatus())) {
            Long lockTime = System.currentTimeMillis() - waimai.getLockTime().getTime();
            if(lockTime > 0 && lockTime < (order_lock_pay_time * 1000)){
                res.setData(StatusInfo.BUSINESS);
                res.setSubMsg("订单正在支付");
                return res;
            }else{
                waimaiLock.setId(waimai.getId());
                waimaiLock.setLockTime(new Date());
                waimaiServiceApi.updateWaimai(waimaiLock);
            }
        }


        //使用积分抵扣
        double payTotalPrice = waimai.getTotalPrice();
        if(PayMotionConstants.Whether.TRUE.getValue().equals(vipPayEntryVO.getIsConsumePoints())){
            payTotalPrice = payMotionApi.consumePointsInit(waimai, PayMotionConstants.Whether.TRUE.getValue());
            //是否由积分抵扣完成
            boolean pointsFree = checkOrderPointsFree(waimai,PayMotionConstants.OrderPayModel.MEMBER_CARD.getValue(), vipPayEntryVO);
            if(pointsFree){
                //返回成功
                res.setSubMsg("支付成功");
                return res;
            }
        }

        if(waimai.getTotalPrice() == 0){
            PayEntryVO payEntryVO = new PayEntryVO();
            BeanUtils.copyProperties(vipPayEntryVO,payEntryVO);
            finishOrderWhenPaySuccess(waimai,payEntryVO);
            //返回成功
            res.setSubMsg("支付成功");
            return res;
        }

        // 店内点餐折扣
        Double discountRate = 10.0d;
        // 消息推送方式
        Integer aliyunMqtt = 0;
        // 配置了秒付数据回流后，推送商家消息至主机
        Long hostMachineId = null;
        Integer isChainStore = 0;
        //会员卡支付集团账户优先（会员）
        Integer memberPayFirstGroup = 0;
        //在线订单是否需要员工验证
        Integer employeeInvalid = 0;

        if (null != shopperConfig) {
            discountRate = (null == shopperConfig.get("CTR_SWEEP_DISCOUNT_RATE")
                    || Utils.isEmpty(shopperConfig.get("CTR_SWEEP_DISCOUNT_RATE").toString())) ? 10.0d
                    : Double.valueOf(shopperConfig.get("CTR_SWEEP_DISCOUNT_RATE").toString());
            aliyunMqtt = (null == shopperConfig.get("CTR_ALIYUN_MQTT")
                    || Utils.isEmpty(shopperConfig.get("CTR_ALIYUN_MQTT").toString())) ? 0
                    : Integer.valueOf(shopperConfig.get("CTR_ALIYUN_MQTT").toString());
            Integer onlineDataBackflow = (null == shopperConfig.get("ONLINE_ORDER_DATA_BACKFLOW")
                    || Utils.isEmpty(shopperConfig.get("ONLINE_ORDER_DATA_BACKFLOW").toString())) ? 0
                    : Integer.valueOf(shopperConfig.get("ONLINE_ORDER_DATA_BACKFLOW").toString());
            if (new Integer(1).equals(onlineDataBackflow)) {
                // 获取数据回流主机Id
                EpayShopConfig epayShopConfig = shopperInfoServiceApi.getEpayShopConfig(waimai.getShopId());
                if (epayShopConfig != null) {
                    hostMachineId = epayShopConfig.getMachineId();
                }
            }
            isChainStore = (null == shopperConfig.get("CTR_VIP_CHAIN_STORE")
                    || Utils.isEmpty(shopperConfig.get("CTR_VIP_CHAIN_STORE").toString())) ? 0
                    : Integer.valueOf(shopperConfig.get("CTR_VIP_CHAIN_STORE").toString());

            memberPayFirstGroup = (null == shopperConfig.get("CTR_MEM_PAY_FIRST_GROUP")
                    || Utils.isEmpty(shopperConfig.get("CTR_MEM_PAY_FIRST_GROUP").toString())) ? 0
                    : Integer.valueOf(shopperConfig.get("CTR_MEM_PAY_FIRST_GROUP").toString());

            employeeInvalid = (null == shopperConfig.get("CTR_SWEEP_EMPLOYEE_INVALID")
                    || Utils.isEmpty(shopperConfig.get("CTR_SWEEP_EMPLOYEE_INVALID").toString())) ? 0
                    : Integer.valueOf(shopperConfig.get("CTR_SWEEP_EMPLOYEE_INVALID").toString());
        }

        Double totalPriceAfterDiscount = Arith.round(Arith.mul(payTotalPrice, Arith.div(discountRate, 10)), 2);
        Map<String, String> nameValuePair = new HashMap<String, String>();
        ShopperAndParent shopper = shopperInfoServiceApi.getShopperAndParent(waimai.getShopId());
        nameValuePair.put("shopperId", shopper.getId() + "");
        nameValuePair.put("uid", uid);
        nameValuePair.put("shopperPName", shopper.getParentInfo().getNick());
        nameValuePair.put("orderId", orderNum);
        nameValuePair.put("totalPay", totalPriceAfterDiscount + "");
        nameValuePair.put("isChainStore", isChainStore == null ? "0" : isChainStore.toString());
        nameValuePair.put("shopperPId", shopper.getParentId() + "");
        nameValuePair.put("promotionStatus",
                (Arith.sub(waimai.getTotalPrice(), totalPriceAfterDiscount)) > 0 ? "1" : "0");
        nameValuePair.put("promotionPrice", (Arith.sub(waimai.getTotalPrice(), totalPriceAfterDiscount)) + "");
        nameValuePair.put("shopperName", shopper.getNick());
        nameValuePair.put("payment", "20");
        nameValuePair.put("firstAccount", memberPayFirstGroup + "");
        nameValuePair.put("state", "1");
        nameValuePair.put("recordFrom", "2");
        String sign = MD5.md5crypt(
                customCommonCode + shopper.getId() + customPublicKey + customSpecialCode + totalPriceAfterDiscount);
        nameValuePair.put("sign", sign);
        logger.info("会员卡支付入参"+nameValuePair);
        CoreResponse<String> result = HttpUtils.doPostForm(memberUrl + "/waiMaiInterface/saveConsume.htm",
                nameValuePair, 60000, 60000, "UTF-8");
        logger.info("会员卡支付================orderNum"+orderNum+"==========uid+"+uid+"================result"+JSONObject.parseObject(result.getData())+"=================nameValuePair"+nameValuePair);
        if (!Utils.isEmpty(result.getData())) {
            JSONObject jo = JSONObject.parseObject(result.getData());
            if (jo.getBooleanValue("success")) {
                int msgType = 0;
                waimai.setPayModel(20);
                waimai.setPayTime(new Date());
                waimai.setPayStatus(1);
//                waimai.setTotalPay(totalPriceAfterDiscount);
                //add by litao 2019年03月18日  不保存商家优惠字段promotionprice
//				waimai.setPromotionPrice((Arith.sub(waimai.getTotalPrice(), totalPriceAfterDiscount)));
//                waimai.setTotalPrice(totalPriceAfterDiscount);

                //积分支付回调的时候加入订单支付金额
                double totalPriceAll = totalPriceAfterDiscount;
                OrderPayDetail orderPayDetailByPoints = payMotionApi.getOrderPayDetailByOrderNumAndPayModel(orderNum, PayMotionConstants.OrderPayModel.MEMBER_CONSUME_POINTS.getValue());
                if(orderPayDetailByPoints != null){
                    totalPriceAll = Arith.add(totalPriceAll,orderPayDetailByPoints.getTotalPrices());
                }
//                waimai.setTotalPrice(totalPriceAll);
                waimai.setTotalPay(totalPriceAll);

                waimai.setTradeNo(jo.getString("serialId"));
                //add by ywc 2018年5月15日 会员卡支付保存订单支付金额
                waimai.setTotalFee(totalPriceAll);
                //在线订单
                if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(clientOrderMode)
                || Constants.clientOrderMode.WAIMAI_ORDER_MODE.getValue().equals(clientOrderMode)){
                    msgType = 2;
                    waimai.setOrderStatus(0);
                    //扫码下单
                }else{
                    // 增加了将取消订单被支付后改为0（出现条件：H5结账的同时，同桌取消了订单）
                    if (new Integer(-1).equals(waimai.getOrderStatus())
                            || new Integer(12).equals(waimai.getOrderStatus())) {
                        msgType = 1;
                        waimai.setOrderStatus(0);
                    }
                }
                //开启员工验证时，如果没有传入手机号则从员工表中获取
                if (new Integer(1).equals(employeeInvalid) && Utils.isEmpty(waimai.getBuyerPhone())) {
                	Employee employee = employeeService.getEmployeeEntry(shopper.getParentId(),
                            shopper.getId(), CommonConstants.EmployeeAuthSource.ALIPAY.getValue(), appId, buyerId);
                	if(!Utils.isEmpty(employee)){
                		waimai.setBuyerPhone(employee.getPhone());
                	}
                }
                //在线订单支付后写入订单超时记录表
                if((Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue()).equals(clientOrderMode)
                        || (Constants.clientOrderMode.WAIMAI_ORDER_MODE.getValue()).equals(clientOrderMode)){
                    //获取订单超时记录表是否已经存在记录
                    ReceiptTimeoutWaimai receiptWaimai = waimaiServiceApi.getReceiptTimeoutWaimai(orderNum);
                    if(receiptWaimai==null){
                        Date date = new Date();
                        //十分钟之后
                        date.setTime(date.getTime()+10*60*1000);
                        if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(waimai.getOuterSupportId())){
                            waimai.setReceiptTimeout(date);
                        }
                        receiptWaimai = new ReceiptTimeoutWaimai();
                        receiptWaimai.setOrderNum(orderNum);
                        receiptWaimai.setOuterSupportId(waimai.getOuterSupportId());
                        receiptWaimai.setReceiptTimeout(date);
                        receiptWaimai.setStoreId(waimai.getShopId());
                        //新增在线订单订单超时记录信息
                        waimaiServiceApi.saveReceiptTimeoutWaimai(receiptWaimai);
                    }
                }
                waimai.setUid(uid);

                // 支付类型编码
                if(null != waimai.getPayModel()){
                    PayModel payModelWaimai = alipayServiceApi.getPayCodeByPayModel(waimai.getPayModel());
                    if(payModelWaimai!=null){
                        waimai.setPayCode(null == payModelWaimai.getPayCode()&& "".equals(payModelWaimai.getPayCode())?null:payModelWaimai.getPayCode());
                    }
                }
                //20200609 存储支付明细
                Waimai waimaiDetailsSave = new Waimai();
                BeanUtils.copyProperties(waimai,waimaiDetailsSave);
                String payOrderNum = waimai.getOrderNum()+RandomUtil.getRandomNum(3);
                waimaiDetailsSave.setPayOrderNum(payOrderNum);
                waimaiDetailsSave.setTotalPrice(totalPriceAfterDiscount);
                waimaiDetailsSave.setTotalFee(totalPriceAfterDiscount);
                waimaiDetailsSave.setTotalPay(totalPriceAfterDiscount);
                payMotionApi.saveOrderPayDetails(waimaiDetailsSave);

                //20200609 会员积分消费执行
                OrderPayDetail orderPayDetail = payMotionApi.getOrderPayDetailByOrderNumAndPayModel(waimai.getOrderNum(), PayMotionConstants.OrderPayModel.MEMBER_CONSUME_POINTS.getValue());
                if(orderPayDetail != null && PayMotionConstants.PayDetailPayStatus.UNPAID.getValue().equals(orderPayDetail.getPayStatus())){
                    //积分混合使用，改变为混合支付
                    PayModel payModelWaimai = alipayServiceApi.getPayCodeByPayModel(orderPayDetail.getPayModel());
                    orderPayDetail.setPayCode(payModelWaimai.getPayCode());
                    orderPayDetail = payMotionApi.executeConsumePoints(waimai, orderPayDetail);
                    waimai.setPayModel(Constants.payModel.BLEND_PAY.getValue());
                    if(orderPayDetail == null){
                        throw new RuntimeException("积分消费失败");
                    }
                }

                if(null != waimai.getPayModel()){
                    PayModel payModel = alipayServiceApi.getPayCodeByPayModel(waimai.getPayModel());
                    if (payModel != null) {
                        waimai.setPayCode(payModel.getPayCode());
                    }
                }
                waimaiServiceApi.updateWaimai(waimai);

                // 获取用户信息
                ThirdUserInfo thirdUserInfo = shopperInfoServiceApi.getThirdUserInfo(buyerId, 1);
                if (null == thirdUserInfo) {
                    thirdUserInfo = shopperInfoServiceApi.getThirdUserInfo(buyerId, 2);
                }
                if (null != thirdUserInfo){
                    // add by yxy 2019年3月19日 15:00:39 创建订单时保存订单操作关联表
                    WaimaiOperateRelated operateRelated = new WaimaiOperateRelated();
                    // 商家Id
                    operateRelated.setShopId(waimai.getShopperId());
                    // 店铺Id
                    operateRelated.setStoreId(waimai.getShopId());
                    // 订单号
                    operateRelated.setOrderNum(waimai.getOrderNum());
                    // 订单来源
                    operateRelated.setOuterSupportId(waimai.getOuterSupportId());
                    // 订单下单时间
                    operateRelated.setOrderDate(waimai.getCreateTime());
                    // 操作时间类型
                    operateRelated.setTimeType(CommonConstants.WaimaiOperateTimeType.ORDER_PAY.getValue());
                    // 操作时间
                    operateRelated.setOperateTime(new Date());
                    // 操作人员类型
                    operateRelated.setOperatorType(CommonConstants.WaimaiOperatorType.CUSTOMER.getValue());
                    // 操作人员Id
                    operateRelated.setOperatorId(thirdUserInfo.getId());
                    // 操作人员员工号 扫码点餐不存
                    operateRelated.setOperatorNum(null);
                    // 操作人员的昵称或者名称
                    operateRelated.setOperatorNick(thirdUserInfo.getNickName() == null ? "吃货" : thirdUserInfo.getNickName());
                    // 订单创建时间
                    operateRelated.setCreateTime(new Date());
                    waimaiServiceApi.saveWaimaiOperateRelated(operateRelated);
                }
                // 调用支付宝上传接口上传订单
                waimaiServiceApi.uploadOrder(waimai, waimai.getOrderNum(), koubeiUploadUrl,
                        uploadOrderFlag,waimai.getOuterSupportId());
                DiningArea tableInfo = null;
                if (!Utils.isEmpty(waimai.getTableNum()) && !Utils.isEmpty(waimai.getTableUid())) {
                    tableInfo = shopperInfoServiceApi.getDiningAreaByUid(waimai.getTableUid());
                }
                String msgCode = Utils.createOrderNum(waimai.getShopId());
                // 配置了秒付数据回流后，推送商家消息至主机
                webMsgService.sendWebMsg(waimai, (tableInfo==null?null:tableInfo.getMachineId()), msgType, aliyunMqtt, hostMachineId,msgCode);
                // add by ywc 2019年11月27日 	增加下单消息保存
    			ShopperConfig sweepPayPrintObj = shopperInfoServiceApi.getShopperConfig(waimai.getShopId(), "CTR_SWEEP_PAY_PRINT");
    			Integer sweepPayPrint = sweepPayPrintObj == null ? 0 : Integer.valueOf(sweepPayPrintObj.getPropValue());
    			webMsgService.saveAddWaimaiMsgRecord(sweepPayPrint, waimai, tableInfo, hostMachineId, msgCode);
                // 生活号结账通知
                waimaiServiceApi.sendServiceWindowMsg(waimai, shopper.getAlipayUserId(), shopper.getNick(),
                        shopper.getAddress(), sweepUrl, serviceWindowUrl, "3");

                //核销优惠订单 20200407
                payMotionApi.executeVouchersVerify(waimai);
                return res;
            } else {
                res.setStatusInfo(CoreResponse.StatusInfo.FORBIDDEN);
                res.setMsg("支付失败");
                return res;
            }
        } else {
            res.setStatusInfo(CoreResponse.StatusInfo.FORBIDDEN);
            res.setMsg("支付失败");
            return res;
        }
    }

    @Override
    public void cancelAlipayOrder(Integer storeId, String orderNum, String outTradeNo, String cancelJSON) {
        Shopper shopper = shopperInfoServiceApi.getShopper(storeId);
        if(StringUtils.isEmpty(shopper.getAlipayUserId())){
            logger.info("撤单失败，商家alipayUserId为空 storeId：" + storeId + "，orderNum：" + orderNum);
            return;
        }
        ShopperExtend shopperExtend = shopperInfoServiceApi.getShopperExtend(storeId);
        AlipayApplyAuthToken authToken = null;
        // 获取商家支付宝支付方式
        int payMethod = (new Integer(1).equals(shopperExtend.getPaymentMethod())
                || shopperExtend.getPaymentMethod() == null) ? 1 : 2;
        if (payMethod == 1
                && (Utils.isEmpty(shopperExtend.getAlipayAppId()) || Utils.isEmpty(shopperExtend.getAlipayPrivateKey())
                || Utils.isEmpty(shopperExtend.getAlipayAlipayPublicKey()))) {
            payMethod = 2;
        }
        if (payMethod == 2) {
            AlipayApplyAuthToken token = new AlipayApplyAuthToken();
            token.setAlipayUserId(shopper.getAlipayUserId());
            authToken = getAlipayApplyAuthToken(token);
            payMethod = authToken == null ? 1 : payMethod;
        }
        AlipayClient alipayClient = AlipayUtils.initAlipayClient(PRIVATE_KEY, ALIPAY_PUBLIC_KEY, shopperExtend,
                authToken, payMethod);
        AlipayTradeCancelRequest aliPayRequest = new AlipayTradeCancelRequest();
        try {
            List<WaimaiSerialnumber> serialList = waimaiServiceApi.getWaimaiSerialnumberByOrderNum(orderNum);
            if (!Utils.isEmpty(serialList)) {
                for (WaimaiSerialnumber s : serialList) {
                    JSONObject json = new JSONObject();
                    String out_trade_no = s.getOutTradeNo();
                    String trade_no = s.getTradeNo();
                    if (!Utils.isEmpty(out_trade_no)) {
                        json.put("out_trade_no", out_trade_no);
                        json.put("trade_no", trade_no);
                        aliPayRequest.setBizContent(json.toJSONString());
                        if (authToken != null) {
                            aliPayRequest.putOtherTextParam("app_auth_token", authToken.getAuthToken());
                        }
                        AlipayTradeCancelResponse response = alipayClient.execute(aliPayRequest);
                        // 如果支付失败，有可能token失效，刷新token
                        if (payMethod == 2 && (null == response || !response.isSuccess())) {
                            authToken = flushAuthToken(authToken);
                            if (authToken != null) {
                                aliPayRequest.putOtherTextParam("app_auth_token", authToken.getAuthToken());
                                // 再次执行
                                response = alipayClient.execute(aliPayRequest);
                            }
                        }
                        if (null != response && response.isSuccess()) {
                            JSONObject jsonObj = JSONObject.parseObject(response.getBody())
                                    .getJSONObject("alipay_trade_cancel_response");
                            if ("10000".equals(jsonObj.getString("code"))) {
                                logger.info("撤单成功，storeId：" + storeId + "，orderNum：" + orderNum + "，"
                                        + jsonObj.toJSONString());
                                waimaiServiceApi.deleteWaimaiSerialNumberByOutTradeNo(out_trade_no);
                            } else {
                                logger.info("撤单失败，storeId：" + storeId + "，orderNum：" + orderNum + "，"
                                        + jsonObj.toJSONString());
                            }
                        } else {
                            logger.info(
                                    "撤单失败，storeId：" + storeId + "，orderNum：" + orderNum + "，" + response.getSubMsg());
                        }
                    } else {
                        waimaiServiceApi.deleteWaimaiSerialNumberByOutTradeNo(out_trade_no);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("撤单失败，storeId：" + storeId + "，orderNum：" + orderNum + "，" + e.toString());
        }

    }

    @Override
    public CoreResponse<WechatPayVO> wechatPay(HttpServletResponse response, WechatPayEntryVO wechatPayEntry) {
        //logger.info("扫码下单聚合支付开始获取参数："+request.getRequestURL().toString()+"?"+RequestContext.requestParams(request));
        CoreResponse<WechatPayVO> res = new CoreResponse<WechatPayVO>();
        WechatPayVO wechatPay = new WechatPayVO();
        String orderNum = wechatPayEntry.getOrderNum();
        String buyerId = wechatPayEntry.getBuyerId();
        String buyerNick = wechatPayEntry.getBuyerNick();
        String uid = wechatPayEntry.getUid();
        String sub_appid = wechatPayEntry.getSub_appid();
        Integer is_mini_program_pay = wechatPayEntry.getIs_mini_program_pay();

        try{
            Waimai waimai = waimaiServiceApi.getWaimaiByOrderNum(orderNum);
            if(waimai == null){
                res.setStatusInfo(StatusInfo.ERROR_40001);
                res.setSubMsg("支付失败，订单不存在");
                return res;
            }
            if(Constants.payStatus.PAYSTATUS_ONE.getValue().equals(waimai.getPayStatus())){
                res.setStatusInfo(StatusInfo.ERROR_40001);
                res.setSubMsg("订单已支付");
                return res;
            }
            if(Constants.orderStatus.STATUS_THREE.getValue().equals(waimai.getOrderStatus())){
                res.setStatusInfo(StatusInfo.ERROR_40001);
                res.setSubMsg("商家还未接单，请联系商家");
                return res;
            }

            // 获取店铺配置信息
            Map<String, Object> shopperConfig = shopperInfoServiceApi.getShopperAllConfig(waimai.getShopId());
            String isOpenOrderLock = null == shopperConfig.get("IS_OPEN_ORDER_LOCK") ? "" : shopperConfig.get("IS_OPEN_ORDER_LOCK").toString();
            // 订单锁状态
            Integer lockStatus =  waimai.getLockStatus() == null ? 0 : waimai.getLockStatus();
            // 新增支付时添加锁,防止重复支付
            Waimai waimaiLock = new Waimai();
            if (new Integer(0).equals(lockStatus)) {
                waimaiLock.setId(waimai.getId());
                if ("1".equals(isOpenOrderLock)) {
                    waimaiLock.setLockStatus(4);
                } else {
                    waimaiLock.setLockStatus(5);
                }
                waimaiLock.setLockTime(new Date());
                waimaiServiceApi.updateWaimai(waimaiLock);
            }
            // 如果生成锁的时间超过设置时间则锁失效，重新更新锁时间
            if (waimai.getLockTime() != null && new Integer(4).equals(waimai.getLockStatus())) {
                Long lockTime = System.currentTimeMillis() - waimai.getLockTime().getTime();
                if(lockTime > 0 && lockTime < (15 * 1000)){
                    wechatPay.setFlag(4);
                    res.setData(wechatPay);
                    res.setSubMsg("订单正在支付");
                    return res;
                }
                waimaiLock.setId(waimai.getId());
                waimaiLock.setLockTime(new Date());
                waimaiServiceApi.updateWaimai(waimaiLock);
            }
            // 如果生成锁的时间超过设置时间则锁失效，重新更新锁时间
            if (waimai.getLockTime() != null && new Integer(5).equals(waimai.getLockStatus())) {
                Long lockTime = System.currentTimeMillis() - waimai.getLockTime().getTime();
                if(lockTime > 0 && lockTime < (order_lock_pay_time * 1000)){
                    wechatPay.setFlag(4);
                    res.setData(wechatPay);
                    res.setSubMsg("订单正在支付");
                    return res;
                }else{
                    waimaiLock.setId(waimai.getId());
                    waimaiLock.setLockTime(new Date());
                    waimaiServiceApi.updateWaimai(waimaiLock);
                }
            }

            //使用积分抵扣
            if(PayMotionConstants.Whether.TRUE.getValue().equals(wechatPayEntry.getIsConsumePoints())){
                double payTotalPrice = payMotionApi.consumePointsInit(waimai, PayMotionConstants.Whether.TRUE.getValue());
                //是否由积分抵扣完成
                boolean pointsFree = checkOrderPointsFree(waimai,waimai.getPayModel(), wechatPayEntry);
                waimai.setTotalPrice(payTotalPrice);
                if(pointsFree){
                    //返回成功
                    wechatPay.setFlag(3);
                    wechatPay.setState(0);
                    res.setData(wechatPay);
                    res.setSubMsg("支付成功");
                    return res;
                }
            }

            if(waimai.getTotalPrice() == 0){
                PayEntryVO payEntryVO = new PayEntryVO();
                BeanUtils.copyProperties(wechatPayEntry,payEntryVO);
                finishOrderWhenPaySuccess(waimai,payEntryVO);
                //返回成功
                wechatPay.setFlag(3);
                wechatPay.setState(0);
                res.setData(wechatPay);
                res.setSubMsg("支付成功");
                return res;
            }

            //如果采用第三方支付，需要提前保存预点餐顾客手机号及取餐时间
            if (!StringUtils.isEmpty(wechatPayEntry.getBuyerPhone())
                    || !StringUtils.isEmpty(wechatPayEntry.getReachTime())) {
                Waimai payWaimai = new Waimai();
                payWaimai.setId(waimai.getId());
                payWaimai.setBuyerPhone(wechatPayEntry.getBuyerPhone());
                if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(waimai.getOuterSupportId())){
                    payWaimai.setReachTime(wechatPayEntry.getReachTime());
                }
                waimaiServiceApi.updateWaimai(payWaimai);
            }
            // 获取用户信息
            ThirdUserInfo thirdUserInfo = shopperInfoServiceApi.getThirdUserInfo(buyerId, 2);
            if (null != thirdUserInfo) {
                // add by yxy 2019年3月19日 15:00:39 创建订单时保存订单操作关联表
                WaimaiOperateRelated operateRelated = new WaimaiOperateRelated();
                // 商家Id
                operateRelated.setShopId(waimai.getShopperId());
                // 店铺Id
                operateRelated.setStoreId(waimai.getShopId());
                // 订单号
                operateRelated.setOrderNum(waimai.getOrderNum());
                // 订单来源
                operateRelated.setOuterSupportId(waimai.getOuterSupportId());
                // 订单下单时间
                operateRelated.setOrderDate(waimai.getCreateTime());
                // 操作时间类型
                operateRelated.setTimeType(CommonConstants.WaimaiOperateTimeType.ORDER_PAY.getValue());
                // 操作时间
                operateRelated.setOperateTime(new Date());
                // 操作人员类型
                operateRelated.setOperatorType(CommonConstants.WaimaiOperatorType.CUSTOMER.getValue());
                // 操作人员Id
                operateRelated.setOperatorId(thirdUserInfo.getId());
                // 操作人员员工号 扫码点餐不存
                operateRelated.setOperatorNum(null);
                // 操作人员的昵称或者名称
                operateRelated.setOperatorNick(thirdUserInfo.getNickName() == null ? "吃货" : thirdUserInfo.getNickName());
                // 订单创建时间
                operateRelated.setCreateTime(new Date());
                waimaiServiceApi.saveWaimaiOperateRelated(operateRelated);
            }


            // 调用统一支付聚合微信支付 add by zm 2019年10月17日19:21:16
            String payOrderNum = waimai.getOrderNum()+RandomUtil.getRandomNum(3);
            String url = createUrl(waimai,buyerId,payOrderNum,uid,sub_appid,is_mini_program_pay,wechatPayEntry.getIsConsumePoints());
            wechatPay.setState(1);
            wechatPay.setUrl(url);
            res.setData(wechatPay);
            return res;
        }catch(Exception e){
            e.printStackTrace();
            logger.info("支付失败，未知异常，订单编号："+orderNum+e);
            res.setSubMsg(" 微信支付失败"+e);
            return res;
        }
    }


    /**
     * 生成访问扫呗接口的Url
     * @param waimai
     * @return
     */
    private String createUrl(Waimai waimai,String buyerId,String payOrderNum,String uid,String sub_appid,Integer is_mini_program_pay,Integer isConsumePoints) {
        StringBuffer url = new StringBuffer(antPayUrl+"?");
        try {
            if(waimai != null){
                logger.info("扫呗支付接口调用开始=================orderNum："+waimai.getOrderNum());
                Map<String,Object> params = new HashMap<String,Object>();
                //调用第三方支付方法
                params.put("user_id", buyerId);
                params.put("store_id",waimai.getShopId());
                params.put("total_amount", waimai.getTotalPrice());
                params.put("pay_model", Constants.payModel.SAOBEI_PAY.getValue());
                params.put("channel", "WX");
                params.put("outer_support_id", waimai.getOuterSupportId());
                params.put("invoke_souce",1802);
                params.put("order_num", waimai.getOrderNum());
                params.put("pay_order_num", payOrderNum);
                params.put("sub_appid", sub_appid);
                params.put("is_mini_program_pay", is_mini_program_pay == null ? 0 : is_mini_program_pay);


                String foodOrderType = getFoodOrderType(waimai);
                if (!Utils.isEmpty(foodOrderType)) {
                	params.put("food_order_type", foodOrderType);
                }
                params.put("notify_url",sweepUrl+"/mybank/prePayNotify.htm");
                if(waimai.getMachineId()!=null){
                    params.put("machine_id", waimai.getMachineId());
                }else{
                    List<Machine> machineList = shopperInfoServiceApi.getMachineByStoreId(waimai.getShopId());
                    if(!CollectionUtils.isEmpty(machineList)){
                        params.put("machine_id",machineList.get(0).getId());
                    }
                }
                params.put("subject", URLEncoder.encode(waimai.getBuyNick()+"-消费","UTF-8"));
                Object accessToken = redisService.getObj(buyerId+"_accessToken");
                if(accessToken!=null){
                	
                JSONObject json= new JSONObject();
                json.put("accessToken", String.valueOf(accessToken));
                json.put("uid", uid);
                params.put("attach", json.toString());
                	
                }
                Integer tableInfoId = null;
                if(!StringUtils.isEmpty(waimai.getTableUid())){
                    DiningArea diningArea = shopperInfoServiceApi.getDiningAreaByUid(waimai.getTableUid());
                    tableInfoId = diningArea.getId();
                }
                //back为1给前端放回表示微信扫呗
                String	success = "?back=1&state=1&msg=支付成功&orderNumber="+waimai.getOrderNum()+"&payOrderNum="+payOrderNum;
                String	fail = "?back=1&state=0&msg=支付失败&orderNumber="+waimai.getOrderNum()+"&payOrderNum="+payOrderNum;
               /* //在线订单前端路径
                if(Constants.orderOutSupportId.ONLINE_ORDER.getValue().equals(waimai.getOuterSupportId())) {
                    params.put("success_url", sweepOrderVueUrl+"/#/online/payState/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/"+tableInfoId+success);
                    params.put("fail_url", sweepOrderVueUrl+"/#/online/payState/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/"+tableInfoId+fail);
                    //扫码下地前端路径
                }else {
                    params.put("success_url", sweepOrderVueUrl+"/#/payState/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/"+tableInfoId+success);
                    params.put("fail_url", sweepOrderVueUrl+"/#/payState/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/"+tableInfoId+fail);
                }*/
                if(Constants.orderOutSupportId.ONLINE_ORDER.getValue().equals(waimai.getOuterSupportId())) {
                    params.put("success_url",sweepOrderVueUrl+"/main.html#/online/payState/"+success);
                    params.put("fail_url", sweepOrderVueUrl+"/main.html#/online/payState/"+fail);
                    // 扫码下单跳转路径
                }else {
                    params.put("success_url",sweepOrderVueUrl+"/main.html#/payState/"+success);
                    params.put("fail_url", sweepOrderVueUrl+"/main.html#/payState/"+fail);
                }
/*                params.put("success_url",sweepOrderVueUrl+"/main.html#/payState/"+success);
                params.put("fail_url", sweepOrderVueUrl+"/main.html#/payState/"+fail);
*/                List<BusinessWhiteList> BusinessWhiteList = shopperInfoServiceApi.getShopperBusinessWhiteList(waimai.getShopId(),
                        waimai.getShopperId(), CommConstant.WHILET_NOT_SWEEP_JUMP_PAY_PAGE);
                if (!CollectionUtils.isEmpty(BusinessWhiteList) && Constants.orderOutSupportId.ONLINE_ORDER.getValue().equals(waimai.getOuterSupportId())) {
                    // 支付完成后不跳支付成功页面跳转我的订单页面
                    /*params.put("success_url", sweepOrderVueUrl+"/#/online/orders/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/null?orderNum="+waimai.getOrderNum());
                    params.put("fail_url", sweepOrderVueUrl+"/#/online/payState/"+waimai.getShopId()+"/"+waimai.getBuyerId()+"/"+tableInfoId+fail);*/
                	params.put("success_url",sweepOrderVueUrl+"/#/online/orders?buyerId=" + waimai.getBuyerId() + "&tableInfoId=" + tableInfoId + "&storeId=" + waimai.getShopId() +"orderNum="+waimai.getOrderNum()+"&dm=1");
               	 	params.put("fail_url", sweepOrderVueUrl+"/main.html#/payState/"+fail);
                }
                Map<String,Object> map = new HashMap<String, Object>();
                map.put("out_request_no", Utils.createOrderNum(waimai.getShopId()));
                map.put("method", "blibao.trade.htmlpay");
                map.put("biz_content", URLEncoder.encode(JSONObject.toJSONString(params),"UTF-8"));
                //map.put("biz_content", params);
                for (String key:map.keySet()) {
                    url.append(key+"="+map.get(key)+"&");
                }
                url=url.deleteCharAt(url.length()-1);
                //logger.info("扫呗支付接口调用url组装完毕=================url："+url);
            }
            return url.toString();
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("支付失败，未知异常，订单编号："+waimai.getOrderNum()+","+Utils.log4jDetail(e));
            return null;
        }
    }

    @Override
    public boolean updateAlipayRefund(String orderNum, String refundReason) {
        Waimai waimai = waimaiServiceApi.getWaimaiByOrderNum(orderNum);
        if (waimai == null) {
            return false;
        }
        Integer status = waimai.getOrderStatus();
        //订单状态为0 或1 已支付，订单hexiaoType不为1需要核销   isHexiao未核销
        if ((new Integer(0).equals(status) || new Integer(1).equals(status))
                && new Integer(0).equals(waimai.getIsHexiao()) && !new Integer(1).equals(waimai.getHexiaoType())
                && new Integer(1).equals(waimai.getPayStatus())) {
            if (!Utils.isEmpty(refundReason)) {
                Pattern p = Pattern.compile("\\s*|\t|\r|\n");
                Matcher m = p.matcher(refundReason);
                refundReason = m.replaceAll("");
            }
            Waimai params = new Waimai();
            params.setCancleReason(refundReason);
            params.setOrderStatus(5);
            params.setId(waimai.getId());
            waimaiServiceApi.updateWaimai(params);
            // 调用支付宝上传接口上传订单
            waimaiServiceApi.uploadOrder(waimai, waimai.getOrderNum(), koubeiUploadUrl, uploadOrderFlag,waimai.getOuterSupportId());
            //发送退款消息
            String msgCode = Utils.createOrderNum(waimai.getShopId());
            webMsgService.sendWebMsg(waimai, null, 3, 1, null,msgCode);
            // add by ywc 2019年11月27日 	增加下单消息保存
			ShopperConfig sweepPayPrintObj = shopperInfoServiceApi.getShopperConfig(waimai.getShopId(), "CTR_SWEEP_PAY_PRINT");
			Integer sweepPayPrint = sweepPayPrintObj == null ? 0 : Integer.valueOf(sweepPayPrintObj.getPropValue());
			webMsgService.saveAddWaimaiMsgRecord(sweepPayPrint, waimai, null, null, msgCode);
            return true;
        }
        return false;
    }


    @Override
    public WaimaiTradeInfo getPayTradeInfo(PayTradeEntryVO payTradeEntryVO) {
        WaimaiTradeInfo tradeInfo = new WaimaiTradeInfo();
        String orderNum = payTradeEntryVO.getOrderNum();
        String payOrderNum = payTradeEntryVO.getPayOrderNum();
        Integer count = payTradeEntryVO.getCount();
        //获取订单信息
        Waimai waimai = waimaiServiceApi.getWaimaiByOrderNum(orderNum);
        if(waimai==null){
            return null;
        }
        BeanUtils.copyProperties(waimai, tradeInfo);
        if(new Integer(1).equals(waimai.getPayStatus())){
            return tradeInfo;
        }
        if(count <= new Integer(3) && !StringUtils.isEmpty(payOrderNum)){
            JSONObject contentJson = new JSONObject();
            contentJson.put("order_num", waimai.getOrderNum());
            contentJson.put("machine_id", waimai.getMachineId());
            contentJson.put("store_id", waimai.getShopId());
            contentJson.put("pay_order_num",payOrderNum );
            if(waimai.getMachineId()!=null){
                contentJson.put("machine_id", waimai.getMachineId());
            }else{
                List<Machine> machineList = shopperInfoServiceApi.getMachineByStoreId(waimai.getShopId());
                if(!CollectionUtils.isEmpty(machineList)){
                    contentJson.put("machine_id",machineList.get(0).getId());
                }
            }
            Map<String,String> map = new HashMap<String, String>();
            map.put("out_request_no",Utils.createOrderNum(waimai.getShopId()));
            map.put("method", "blibao.trade.query");
            map.put("biz_content",JSONObject.toJSONString(contentJson));
            logger.info("查询第三方支付参数："+JSONObject.toJSONString(map.toString()));
            CoreResponse<String> result = HttpUtils.doPostForm(payOrderUrl, map , 60000, 60000, "UTF-8");
            logger.info("查询第三方支付返回结果："+JSONObject.toJSONString(result));
            if (null != result && !Utils.isEmpty(result.getData())) {
                JSONObject json = JSONObject.parseObject(result.getData());
                if(json.getBoolean("success") && ("TRADE_SUCCESS").equals(json.getString("trade_status"))){
                    payOrderNotify(json.getJSONObject("data"),waimai);
                    BeanUtils.copyProperties(waimai, tradeInfo);
                    return tradeInfo;
                }
            }
        }
        return tradeInfo;
    }

    /**
     * 第三方支付成功,waimai订单失败，重新写入waimai订单数据
     */
    public String payOrderNotify(JSONObject data,Waimai waimai){
        try {
            // 买家支付宝登录账号
            String buyerLogonId = data.getString("buyer_logon_id");
            //买家支付金额
            String totalPayStr = data.getString("buyer_pay_amount");
            //买家支付宝或者微信用户id
            String buyerUserId = data.getString("buyer_user_id");
            //可打折金额
            String discountableAmountStr = data.getString("discountable_amount");
            //交易时间
            String gmtPayment = data.getString("gmt_payment");
            //发票金额
            String invoiceAmountStr = data.getString("invoice_amount");
            //订单号
            String orderNum = data.getString("order_num");
            //商户入驻id
            String partner = data.getString("partner");
            //支付方式
            String payModel = data.getString("pay_model");
            //电子支付平台优惠
            String payPlatformPromotionFeeStr = data.getString("pay_platform_promotion_amount");
            //商家实收
            String totalPriceStr = data.getString("receipt_amount");
            //商家优惠金额
            String shopPromotionAmountStr = data.getString("shop_promotion_amount");
            //订单原价
            String totalFeeStr = data.getString("total_amount");
            //交易号
            String tradeNo = data.getString("trade_no");
            //不可打折金额
            String undiscountableAmountStr = data.getString("undiscountable_amount");

            Double totalFee = Utils.isEmpty(totalFeeStr)?0d:Double.valueOf(totalFeeStr);//订单原价
            Double totalPrice = Utils.isEmpty(totalPriceStr)?0d:Double.valueOf(totalPriceStr);//商家实收（仅支付宝返回）（扣手续费之前） ？？？ 这里和支付宝返回不一样？
            Double totalPay = Utils.isEmpty(totalPayStr)?0d:Double.valueOf(totalPayStr);//用户实付金额
            Double thirdPromotionFee = Utils.isEmpty(shopPromotionAmountStr)?0d:Double.valueOf(shopPromotionAmountStr);// 商家在第三方平台优惠(商家优惠)
            Double payPlatformPromotionFee = Utils.isEmpty(payPlatformPromotionFeeStr)?0d:Double.valueOf(payPlatformPromotionFeeStr);// 电子支付平台优惠

            ShopperAndParent shopper = shopperInfoServiceApi.getShopperAndParent(waimai.getShopId());
            int msgType = 0;
            //增加了将取消订单被支付后改为0（出现条件：H5结账的同时，同桌取消了订单）
            if(new Integer(-1).equals(waimai.getOrderStatus()) || new Integer(12).equals(waimai.getOrderStatus())) {
                msgType = 1;
                waimai.setOrderStatus(0);
            }
            if(new Long(4).equals(waimai.getOuterSupportId())){
                msgType = 2;
            }
            //在线订单 订单状态支付后改变
            if(Constants.orderOutSupportId.ONLINE_ORDER.getValue().equals(waimai.getOuterSupportId())
                || Constants.orderOutSupportId.WAIMAI_ORDER.getValue().equals(waimai.getOuterSupportId())){
                msgType = 2;
                if(new Integer(-1).equals(waimai.getOrderStatus())){
                    waimai.setOrderStatus(0);
                }
                //扫码下单
            }else{
                // 增加了将取消订单被支付后改为0（出现条件：H5结账的同时，同桌取消了订单）
                if (new Integer(-1).equals(waimai.getOrderStatus()) || new Integer(12).equals(waimai.getOrderStatus())) {
                    msgType = 1;
                    waimai.setOrderStatus(0);
                }
            }

            //积分支付回调的时候加入订单支付金额
            OrderPayDetail orderPayDetailByPoints = payMotionApi.getOrderPayDetailByOrderNumAndPayModel(orderNum, PayMotionConstants.OrderPayModel.MEMBER_CONSUME_POINTS.getValue());
            double orderTotalPay = totalPay;
            double orderTotalPrice = totalPrice;
            double orderTotalFee = totalFee;
            if(orderPayDetailByPoints != null){
                orderTotalPay = Arith.add(orderTotalPay,orderPayDetailByPoints.getTotalPay());
                orderTotalFee = Arith.add(orderTotalFee,orderPayDetailByPoints.getTotalFee());
                orderTotalPrice = Arith.add(orderTotalPrice,orderPayDetailByPoints.getTotalPrices());
            }

            waimai.setPayStatus(1);
            if(!Utils.isEmpty(payModel)){
                waimai.setPayModel(Integer.valueOf(payModel));
            }
            waimai.setPayTime(new Date());
            waimai.setLockStatus(0);
            waimai.setTradeNo(tradeNo);
            waimai.setTotalPay(orderTotalPay);
            waimai.setThirdPromotionFee(thirdPromotionFee);
            waimai.setTotalPrice(orderTotalPrice);
            waimai.setPayplatformPromotionFee(payPlatformPromotionFee);
            waimai.setThirdPromotionFee(thirdPromotionFee);
            waimai.setTotalFee(orderTotalFee);
            waimai.setIsOtherPay(new Integer(0));
            //add by litao 2019年03月18日  不保存商家优惠字段promotionprice
//			waimai.setPromotionPrice(Arith.sub(waimai.getOriginalPrice(), receiptAmount));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //在线订单支付后写入订单超时记录表
            if((Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue()).equals(waimai.getOuterSupportId())
                    || (Constants.clientOrderMode.WAIMAI_ORDER_MODE.getValue()).equals(waimai.getOuterSupportId())){
                //获取订单超时记录表是否已经存在记录
                ReceiptTimeoutWaimai receiptWaimai = waimaiServiceApi.getReceiptTimeoutWaimai(orderNum);
                if(receiptWaimai==null){
                    Date date = new Date();
                    if(!StringUtils.isEmpty(gmtPayment)){
                        try {
                            date = sdf.parse(gmtPayment);
                        } catch (ParseException e) {
                            logger.error("支付回调在线订单订单超时时间异常========date"+gmtPayment);
                            e.printStackTrace();
                        }
                    }
                    //十分钟之后商家未接单会自动退款
                    date.setTime(date.getTime()+10*60*1000);
                    //waimai表记录在线订单支付后超时时间
                    if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(waimai.getOuterSupportId())){
                        waimai.setReceiptTimeout(date);
                    }
                    receiptWaimai = new ReceiptTimeoutWaimai();
                    receiptWaimai.setOrderNum(orderNum);
                    receiptWaimai.setOuterSupportId(waimai.getOuterSupportId());
                    receiptWaimai.setReceiptTimeout(date);
                    receiptWaimai.setStoreId(waimai.getShopId());
                    //新增在线订单订单超时记录信息
                    waimaiServiceApi.saveReceiptTimeoutWaimai(receiptWaimai);
                }
            }

            // 支付类型编码
            if(null != waimai.getPayModel()){
                PayModel payModelWaimai = alipayServiceApi.getPayCodeByPayModel(waimai.getPayModel());
                if(payModelWaimai!=null){
                    waimai.setPayCode(null == payModelWaimai.getPayCode()&& "".equals(payModelWaimai.getPayCode())?null:payModelWaimai.getPayCode());
                }
            }
            //20200609 存储支付明细
            Waimai waimaiPayDetailsSave = new Waimai();
            BeanUtils.copyProperties(waimai,waimaiPayDetailsSave);
            waimaiPayDetailsSave.setTotalPay(totalPay);
            waimaiPayDetailsSave.setTotalFee(totalFee);
            waimaiPayDetailsSave.setTotalPrice(totalPrice);
            //20200609 回调处理积分消费明细
            OrderPayDetail orderPayDetail = payMotionApi.getOrderPayDetailByOrderNumAndPayModel(waimai.getOrderNum(), PayMotionConstants.OrderPayModel.MEMBER_CONSUME_POINTS.getValue());
            if(orderPayDetail != null && PayMotionConstants.PayDetailPayStatus.UNPAID.getValue().equals(orderPayDetail.getPayStatus())){
                PayModel payModelWaimai = alipayServiceApi.getPayCodeByPayModel(orderPayDetail.getPayModel());
                orderPayDetail.setPayCode(payModelWaimai.getPayCode());
                orderPayDetail = payMotionApi.executeConsumePoints(waimai, orderPayDetail);
                //积分混合使用，改变为混合支付
                waimai.setPayModel(Constants.payModel.BLEND_PAY.getValue());
                if(orderPayDetail == null){
                    throw new RuntimeException("积分消费失败");
                }
            }

            // 支付类型编码
            if(null != waimai.getPayModel()){
                PayModel payModelWaimai = alipayServiceApi.getPayCodeByPayModel(waimai.getPayModel());
                if(payModelWaimai!=null){
                    waimai.setPayCode(null == payModelWaimai.getPayCode()&& "".equals(payModelWaimai.getPayCode())?null:payModelWaimai.getPayCode());
                }
            }
            waimaiServiceApi.updateWaimai(waimai);

            //核销优惠订单 20200407
            payMotionApi.executeVouchersVerify(waimai);

            // 调用支付宝上传接口上传订单 add by ywc 2017年3月15日
            waimaiServiceApi.uploadOrder(waimai, waimai.getOrderNum(), koubeiUploadUrl, uploadOrderFlag,waimai.getOuterSupportId());
            AlipayTradeRecord record = alipayServiceApi.findAlipayTradeRecordByOrderNum(orderNum,waimai.getPayOrderNum());
            if (record == null) {
                record = new AlipayTradeRecord();
                record.setBuyerId(buyerUserId);
                record.setBuyerEmail(buyerLogonId);
                Long machineId = waimai.getMachineId();
                List<Machine> machineList = shopperInfoServiceApi.getMachineByStoreId(waimai.getShopId());
                if (!Utils.isEmpty(machineList) && machineId==null) {
                    machineId = machineList.get(0).getId();
                }
                record.setMachineId(machineId);
                //订单交易记录时间由创建订单时间改为当前时间
                if(StringUtils.isEmpty(gmtPayment)){
                    record.setOrderDate(new Date());
                }else{
                    try {
                        record.setOrderDate(sdf.parse(gmtPayment));
                    } catch (ParseException e) {
                        e.printStackTrace();
                        logger.info("保存交易记录时间异常+++++++++++++++"+gmtPayment);
                    }
                }
                record.setOutTradeNo(waimai.getOrderNum());
                record.setPartner(partner);
                record.setProductCode("WAP");
                record.setProviders(1);
                if(StringUtils.isEmpty(shopper.getAlipayUserId())){
                    record.setSellerId("");
                }else{
                    record.setSellerId(shopper.getAlipayUserId());
                }
                record.setShopperId(waimai.getShopId());
                record.setSubject(waimai.getBuyNick() + "-消费");
                record.setReceiptAmount(totalPrice);
                record.setTotalFee(totalFee);
                record.setTotalPay(totalPay);
                record.setTradeNo(tradeNo);
                record.setVersionNo(2);
                record.setShopParentId(waimai.getShopperId());
                record.setSource(new Integer(5));
                record.setPayOrderNum(waimai.getPayOrderNum());
                // add by hyc 2019年7月8日
                record.setOrderPlaceDate(waimai.getCreateTime());
                record.setPayStatus(new Integer(1));
                int count = alipayServiceApi.saveAlipayTradeRecord(record);
               // logger.info("保存交易记录======count="+count);
            }
            if(null==waimai.getPayStatus() || new Integer(0).equals(waimai.getPayStatus())){
                DiningArea tableInfo = null;
                if (!Utils.isEmpty(waimai.getTableUid())) {
                    tableInfo = shopperInfoServiceApi.getDiningAreaByUid(waimai.getTableUid());
                }
                String msgCode = Utils.createOrderNum(waimai.getShopId());
                webMsgService.sendWebMsg(waimai, (tableInfo == null ? null : tableInfo.getMachineId()), msgType,
                        1, null,msgCode);
                // add by ywc 2019年11月27日 	增加下单消息保存
    			ShopperConfig sweepPayPrintObj = shopperInfoServiceApi.getShopperConfig(waimai.getShopId(), "CTR_SWEEP_PAY_PRINT");
    			Integer sweepPayPrint = sweepPayPrintObj == null ? 0 : Integer.valueOf(sweepPayPrintObj.getPropValue());
    			webMsgService.saveAddWaimaiMsgRecord(sweepPayPrint, waimai, tableInfo, null, msgCode);
            }

            // 有商家优惠，上传商品优惠信息
            if (thirdPromotionFee > 0) {
                Map<String, String> paramMap = new HashMap<String, String>();
                paramMap.put("shopperPid", waimai.getShopperId() + "");
                paramMap.put("shopperId", waimai.getShopId() + "");
                paramMap.put("machineId", waimai.getMachineId() == null ? "" : (waimai.getMachineId() + ""));
                paramMap.put("alipayUserId", partner + "");
                paramMap.put("tradeNo", waimai.getTradeNo());// 交易流水号
                WaimaiExtend waimaiEx = waimaiServiceApi.getWaimaiAndDetailByOrderNum(orderNum);
                JSONArray array = new JSONArray();
                if (waimaiEx != null && waimaiEx.getItems() != null && waimaiEx.getItems().size() > 0) {
                    for (WaimaiItem item : waimaiEx.getItems()) {
                        JSONObject json = new JSONObject();
                        json.put("goods_id", item.getGoodsId());
                        json.put("goods_name", item.getGoodsName());
                        json.put("quantity", item.getBuyCount());
                        json.put("price", item.getOriginalPrice());
                        array.add(json);
                    }
                }
                paramMap.put("goodsDetail", array.toJSONString());
                if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(waimai.getOuterSupportId())){
                    paramMap.put("outerSupportId", "4");
                }else if(Constants.clientOrderMode.SCAN_ORDER_MODE.getValue().equals(waimai.getOuterSupportId())){
                    paramMap.put("outerSupportId", "5");
                }else if(Constants.clientOrderMode.WAIMAI_ORDER_MODE.getValue().equals(waimai.getOuterSupportId())){
                    paramMap.put("outerSupportId", "81");
                }else{
                    paramMap.put("outerSupportId", "103");
                }
                paramMap.put("shopperName", waimai.getShopName());
                CommonThread.execute("上传商品优惠信息", API_SERVICE + "/ajax/saveThirdDiscountVerifyRecord2.htm", paramMap);
            }
            // 生活号结账通知
            ShopperVO shopperVO = new ShopperVO();
            if (shopper != null) {
                BeanUtils.copyProperties(shopper, shopperVO);
                shopperVO.setParentId(shopper.getParentId());
                if (shopper.getParentInfo() != null) {
                    shopperVO.setParentNick(shopper.getParentInfo().getNick());
                    shopperVO.setParentMinLogo(shopper.getParentInfo().getMinLogo());
                }
            }

            waimaiServiceApi.sendServiceWindowMsg(waimai, shopper.getAlipayUserId(), shopper.getNick(),
                    shopper.getAddress(), sweepUrl, serviceWindowUrl, "3");
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("蚂蚁支付宝支付失败："+Utils.log4jDetail(e));
            return null;
        }
    }

    /*
     *<pre>
     * 说    明: 校验订单是否积分抵扣完成
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-28 17:25
     *</pre>
     **/
    private <T> boolean checkOrderPointsFree(Waimai waimai,Integer payModel,T sourceEntry){
        logger.info("系统当前匹配使用payModel="+payModel);
        //涉及积分使用 校验用户积分抵扣是否符合当前订单
        waimai.setPayModel(payModel);
        Integer payModelPoints = payMotionApi.getPayModelByWaimai(waimai);
        logger.info("当前订单最终匹配payModel="+payModelPoints);
        if(PayMotionConstants.OrderPayModel.MIXED.getValue().equals(payModelPoints) || PayMotionConstants.OrderPayModel.MEMBER_CONSUME_POINTS.getValue().equals(payModelPoints)){
//                boolean isEnough = payMotionApi.checkOrderPointsEnoughBeforePay(waimai);
//                if(!isEnough){
//                    logger.info("积分变动，重置订单金额");
//                    Double totalPrice = payMotionApi.consumePointsInit(waimai, 1);
//                    waimai.setTotalPrice(totalPrice);
//                    waimaiServiceApi.updateWaimai(waimai);
//                }

            //查询是否积分抵完，0元支付，直接积分支付完成
            boolean orderFree = payMotionApi.checkOrderFreeByPoints(waimai);
            if(orderFree){
                logger.info("积分完全抵扣，订单直接完成");
                PayEntryVO payEntryVO = new PayEntryVO();
                BeanUtils.copyProperties(sourceEntry,payEntryVO);
                finishOrderWhenPaySuccess(waimai,payEntryVO);
                return true;
            }
        }
        return false;
    }

    /*
     *<pre>
     * 说    明: 支付完成更新订单相关信息
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-24 17:52
     *</pre>
     **/
    private void finishOrderWhenPaySuccess(Waimai waimai, PayEntryVO payEntryVO){
        ShopperAndParent shopper = shopperInfoServiceApi.getShopperAndParent(waimai.getShopId());
        //更新订单信息
        updateWaimaiWhenPaySuccess(waimai,payEntryVO);
        //存储超时记录
        saveReceiptTimeout(waimai);
        //更新与存储支付明细
        finishOrderPayDetails(waimai,payEntryVO.getActualPayModel(),payEntryVO.getActualTotalPay());
        //存储订单用户操作明细
        saveOperateRelated(waimai);
        // 调用支付宝上传接口上传订单
        waimaiServiceApi.uploadOrder(waimai, waimai.getOrderNum(), koubeiUploadUrl, uploadOrderFlag,waimai.getOuterSupportId());
        //发送客户端消息
        sendWebMsgByWaimai(waimai);
        // 代付成功发送消息
        if (PayMotionConstants.Whether.TRUE.getValue().equals(payEntryVO.getIsOtherPay())) {
            sendOtherPayMsg(waimai,payEntryVO);
        }
        // 生活号结账通知
        sendAlipayWindowsMsg(waimai,shopper);
        // 撤销其他等待支付的订单
        List<WaimaiSerialnumber> serialList = waimaiServiceApi.getWaimaiSerialnumberByOrderNum(waimai.getOrderNum());
        if (!Utils.isEmpty(serialList)) {
            cancelWaitPayByWaimai(waimai,serialList,payEntryVO);
        }
        //核销优惠订单 20200407
        payMotionApi.executeVouchersVerify(waimai);
    }


    /*
     *<pre>
     * 说    明: 完成订单更新订单信息
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-28 15:30
     *</pre>
     **/
    private void updateWaimaiWhenPaySuccess(Waimai waimai,PayEntryVO payEntryVO){
        //在线订单 订单状态支付后改变
        Integer outerSupportId = Integer.parseInt(waimai.getOuterSupportId().toString());
        logger.info("waimaiOrderStatus:"+waimai.getOrderStatus());
        if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(outerSupportId)
            || Constants.clientOrderMode.WAIMAI_ORDER_MODE.getValue().equals(outerSupportId)){
            if(new Integer(-1).equals(waimai.getOrderStatus())){
                waimai.setOrderStatus(0);
            }
            String reachTime = payEntryVO.getReachTime();
            //取餐时间更新
            if(!StringUtils.isEmpty(reachTime)){
                waimai.setReachTime(reachTime);
            }
        }else if (new Integer(-1).equals(waimai.getOrderStatus())
            || new Integer(12).equals(waimai.getOrderStatus())) {
            //扫码下单 增加了将取消订单被支付后改为0（出现条件：H5结账的同时，同桌取消了订单）
            waimai.setOrderStatus(0);
        }

        if (!new Integer(1).equals(payEntryVO.getIsOtherPay())) {
            // 代付时不能改变buyerId
            waimai.setBuyerId(payEntryVO.getBuyerId());
        }
        waimai.setPayStatus(1);
        waimai.setPayTime(new Date());
        waimai.setTradeNo(payEntryVO.getTradeNo());
        waimai.setTotalPay(waimai.getTotalPrice());
        waimai.setTotalFee(waimai.getTotalPrice());
        waimai.setThirdPromotionFee(0D);
        waimai.setPayplatformPromotionFee(0D);
        waimai.setIsOtherPay(payEntryVO.getIsOtherPay());
        //更新订单支付锁
        waimai.setLockStatus(0);
        if(!Utils.isEmpty(payEntryVO.getUid())){
            waimai.setUid(payEntryVO.getUid());
        }
        //设置支付订单号
        String payOrderNum = payEntryVO.getPayOrderNum();
        if(Utils.isEmpty(payEntryVO.getPayOrderNum())){
            payOrderNum = waimai.getOrderNum()+ RandomUtil.getRandomNum(3);
        }
        waimai.setPayOrderNum(payOrderNum);
        //获取支付方式
        Integer payModel = payMotionApi.getPayModelByWaimai(waimai);
        waimai.setPayModel(payModel);
        // 支付类型编码
        PayModel payModelWaimai = alipayServiceApi.getPayCodeByPayModel(waimai.getPayModel());
        if(payModelWaimai!=null){
            waimai.setPayCode(payModelWaimai.getPayCode());
        }
        //记录超时记录
        Date receiptTimeout = new Date();
        receiptTimeout.setTime(receiptTimeout.getTime()+10*60*1000);
        if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(outerSupportId)){
            waimai.setReceiptTimeout(receiptTimeout);
        }
        waimaiServiceApi.updateWaimai(waimai);
    }

    /*
     *<pre>
     * 说    明: 存储超时记录
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-28 15:33
     *</pre>
     **/
    private void saveReceiptTimeout(Waimai waimai){
        Integer outerSupportId = Integer.parseInt(waimai.getOuterSupportId().toString());
        //在线订单支付后写入订单超时记录表
        if((Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue()).equals(outerSupportId) || (Constants.clientOrderMode.WAIMAI_ORDER_MODE.getValue()).equals(outerSupportId)){
            //获取订单超时记录表是否已经存在记录
            ReceiptTimeoutWaimai receiptWaimai = waimaiServiceApi.getReceiptTimeoutWaimai(waimai.getOrderNum());
            if(receiptWaimai==null){
                Date receiptTimeout = new Date();
                //十分钟之后商家未接单会自动退款
                receiptTimeout.setTime(receiptTimeout.getTime()+10*60*1000);
                receiptWaimai = new ReceiptTimeoutWaimai();
                receiptWaimai.setOrderNum(waimai.getOrderNum());
                receiptWaimai.setOuterSupportId(waimai.getOuterSupportId());
                receiptWaimai.setReceiptTimeout(receiptTimeout);
                receiptWaimai.setStoreId(waimai.getShopId());
                //新增在线订单订单超时记录信息
                waimaiServiceApi.saveReceiptTimeoutWaimai(receiptWaimai);
            }
        }
    }

    /*
     *<pre>
     * 说    明: 完成消费明细与积分消费
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-28 15:46
     *</pre>
     **/
    private void finishOrderPayDetails(Waimai waimai,Integer actualPayModel,Double actualTotalPay){
        Integer payModel = waimai.getPayModel();
        //积分消费或混合支付下需消费积分
        if(PayMotionConstants.OrderPayModel.MEMBER_CONSUME_POINTS.getValue().equals(payModel)
            || PayMotionConstants.OrderPayModel.MIXED.getValue().equals(payModel)){
            OrderPayDetail orderPayDetail = payMotionApi.getOrderPayDetailByOrderNumAndPayModel(waimai.getOrderNum(), PayMotionConstants.OrderPayModel.MEMBER_CONSUME_POINTS.getValue());
            PayModel payModelWaimai = alipayServiceApi.getPayCodeByPayModel(orderPayDetail.getPayModel());
            orderPayDetail.setPayCode(payModelWaimai.getPayCode());
            orderPayDetail = payMotionApi.executeConsumePoints(waimai, orderPayDetail);
            if(orderPayDetail == null){
                throw new RuntimeException("积分消费失败");
            }
        }

        //存储积分支付外其他支付方式的支付明细
        if(!PayMotionConstants.OrderPayModel.MEMBER_CONSUME_POINTS.getValue().equals(payModel)){
            Waimai waimaiExtend = new Waimai();
            BeanUtils.copyProperties(waimai,waimaiExtend);
            waimaiExtend.setPayModel(actualPayModel);
            waimaiExtend.setTotalFee(actualTotalPay);
            waimaiExtend.setTotalPay(actualTotalPay);
            waimaiExtend.setTotalPrice(actualTotalPay);
            payMotionApi.saveOrderPayDetails(waimaiExtend);
        }
    }

    /*
     *<pre>
     * 说    明: 存储用户操作记录
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-28 15:58
     *</pre>
     **/
    private void saveOperateRelated(Waimai waimai){
        // 获取用户信息
        ThirdUserInfo thirdUserInfo = shopperInfoServiceApi.getThirdUserInfo(waimai.getBuyerId(), 1);
        if (null != thirdUserInfo) {
            // add by yxy 2019年3月19日 15:00:39 创建订单时保存订单操作关联表
            WaimaiOperateRelated operateRelated = new WaimaiOperateRelated();
            // 商家Id
            operateRelated.setShopId(waimai.getShopperId());
            // 店铺Id
            operateRelated.setStoreId(waimai.getShopId());
            // 订单号
            operateRelated.setOrderNum(waimai.getOrderNum());
            // 订单来源
            operateRelated.setOuterSupportId(waimai.getOuterSupportId());
            // 订单下单时间
            operateRelated.setOrderDate(waimai.getCreateTime());
            // 操作时间类型
            operateRelated.setTimeType(CommonConstants.WaimaiOperateTimeType.ORDER_PAY.getValue());
            // 操作时间
            operateRelated.setOperateTime(new Date());
            // 操作人员类型
            operateRelated.setOperatorType(CommonConstants.WaimaiOperatorType.CUSTOMER.getValue());
            // 操作人员Id
            operateRelated.setOperatorId(thirdUserInfo.getId());
            // 操作人员员工号 扫码点餐不存
            operateRelated.setOperatorNum(null);
            // 操作人员的昵称或者名称
            operateRelated.setOperatorNick(thirdUserInfo.getNickName() == null ? "吃货" : thirdUserInfo.getNickName());
            // 订单创建时间
            operateRelated.setCreateTime(new Date());
            waimaiServiceApi.saveWaimaiOperateRelated(operateRelated);
        }
    }

    /*
     *<pre>
     * 说    明: 发送客户端消息
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-28 16:08
     *</pre>
     **/
    private void sendWebMsgByWaimai(Waimai waimai){
        SendMsgToMachineThread sendMsgToMachineThread = new SendMsgToMachineThread(waimai);
        new Thread(sendMsgToMachineThread).start();
    }

    /*
     *<pre>
     * 说    明: 获取推送消息类型
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-28 16:03
     *</pre>
     **/
    private int getSendMsgTypeByWaimai(Waimai waimai){
        Integer clientOrderMode = Integer.parseInt(waimai.getOuterSupportId().toString());
        int msgType;
        if(Constants.clientOrderMode.ONLINE_ORDER_MODE.getValue().equals(clientOrderMode)
                || Constants.clientOrderMode.WAIMAI_ORDER_MODE.getValue().equals(clientOrderMode)){
            msgType = 2;
        }else {
            msgType = 1;
        }
        return msgType;
    }

    /*
     *<pre>
     * 说    明: 代付消息发送
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-28 16:15
     *</pre>
     **/
    private void sendOtherPayMsg(Waimai waimai,PayEntryVO payEntryVO){
        String to = Utils.isEmpty(waimai.getTableUid()) ? waimai.getBuyerId() : waimai.getTableUid();
        Map<String, Object> msg = new HashMap<String, Object>();
        if (!Utils.isEmpty(to)) {
            msg.put("from", "otherPay");
            msg.put("type", "otherPaySuccful");
            msg.put("avatarPath", null);
            msg.put("otherPayBuyerNick", payEntryVO.getBuyerNick());
            if ((new Integer(0)).equals(payEntryVO.getAliyunMqtt())) {
                ActiveMqttUtils.sendMsg(to, JSONObject.toJSONString(msg));
            } else {
                try {
                    AlibabaMQTT.send(to, JSONObject.toJSONString(msg));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        logger.info("代付成功发送消息: " + "to:" + to + "  msg:" + JSONObject.toJSONString(msg));
    }

    /*
     *<pre>
     * 说    明: 发送支付宝生活号结账消息推送
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-28 16:16
     *</pre>
     **/
    private void sendAlipayWindowsMsg(Waimai waimai,ShopperAndParent shopper){
        SendServiceWindowMsgThread sendServiceWindowMsgThread = new SendServiceWindowMsgThread(shopper, waimai, sweepUrl, serviceWindowUrl);
        new Thread(sendServiceWindowMsgThread).start();
    }

    /*
     *<pre>
     * 说    明: 撤销等待支付订单
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-06-28 16:21
     *</pre>
     **/
    private void cancelWaitPayByWaimai(Waimai waimai,List<WaimaiSerialnumber> serialList,PayEntryVO payEntryVO){
        Map<String, String> n = new HashMap<String, String>();
        JSONArray jsonArr = new JSONArray();
        for (WaimaiSerialnumber s : serialList) {
            JSONObject json = new JSONObject();
            json.put("out_trade_no", s.getOutTradeNo());
            json.put("trade_no", s.getTradeNo());
            json.put("pay_status", s.getPayStatus());
            json.put("buyer_id", s.getBuyerId());
            jsonArr.add(json);
        }
        logger.info("=============out_trade_no===================" + jsonArr.toString());
        n.put("cancelJSON", jsonArr.toString());
        n.put("shopperId", waimai.getShopId() + "");
        n.put("orderNum", waimai.getOrderNum());
        n.put("outTradeNo", payEntryVO.getPayOrderNum());
        CommonThread.execute("==========关闭支付宝已支付订单里面的等待支付订单：" + waimai.getOrderNum(), sweepOrderVueUrl + "/pay/cancel", n);
    }

}